其实一开始并没有想到时间上O(n)的方法,想到了也是空间复杂度是O(n)的(需要用到栈或者递归):链表分两段,用栈记录第一段的遍历过程。

后来经提示想到了,可以将第二段链表逆序。从而不需要额外的辅助空间,在O(n)完成。

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//Divide the list into two parts first length n-n/2, second length n/2, reverse serconde part.
//Insert each node in second list into first list.
void reorderList(ListNode *head) {
if(NULL == head || NULL == head -> next) return; //divide
ListNode *p1 = head; ListNode* p2 = head -> next;
for(; p2 != NULL;p1 = p1 -> next, p2 = p2 -> next){
p2 = p2 -> next;
if(p2 == NULL) break;
}
ListNode* temp = p1;
p1 = p1 -> next;
temp -> next = NULL; //reverse second list
ListNode *pre = p1;
if(p1 -> next != NULL){
ListNode* p = p1 -> next;
temp = NULL;
p1 -> next = NULL;
while(p != NULL){
temp = p;
p = p -> next;
temp -> next = pre;
pre = temp;
}
}
ListNode* secHead = pre; //Insert node in second list into first list
ListNode* p = head;
ListNode* temp2 = NULL;
while(secHead != NULL){
temp = p -> next;
temp2 = secHead;
p -> next = temp2;
secHead = secHead -> next;
temp2 -> next = temp;
p = temp;
}
}
};

含测试的代码:

#include<stdio.h> 

struct ListNode {
int m_nValue;
ListNode *next;
ListNode(int x) : m_nValue(x), next(NULL) {}
ListNode(){} }; ListNode* CreateListNode(int value)
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->next = NULL; return pNode;
} void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
if(pCurrent == NULL)
{
printf("Error to connect two nodes.\n");
//exit(1);
} pCurrent->next = pNext;
} void PrintListNode(ListNode* pNode)
{
if(pNode == NULL)
{
printf("The node is NULL\n");
}
else
{
printf("The key in node is %d.\n", pNode->m_nValue);
}
} void PrintList(ListNode* pHead)
{
printf("PrintList starts.\n"); ListNode* pNode = pHead;
while(pNode != NULL)
{
printf("%d\t", pNode->m_nValue);
pNode = pNode->next;
} printf("\nPrintList ends.\n");
} void DestroyList(ListNode* pHead)
{
ListNode* pNode = pHead;
while(pNode != NULL)
{
pHead = pHead->next;
delete pNode;
pNode = pHead;
}
} void AddToTail(ListNode** pHead, int value)
{
ListNode* pNew = new ListNode();
pNew->m_nValue = value;
pNew->next = NULL; if(*pHead == NULL)
{
*pHead = pNew;
}
else
{
ListNode* pNode = *pHead;
while(pNode->next != NULL)
pNode = pNode->next; pNode->next = pNew;
}
} void RemoveNode(ListNode** pHead, int value)
{
if(pHead == NULL || *pHead == NULL)
return; ListNode* pToBeDeleted = NULL;
if((*pHead)->m_nValue == value)
{
pToBeDeleted = *pHead;
*pHead = (*pHead)->next;
}
else
{
ListNode* pNode = *pHead;
while(pNode->next != NULL && pNode->next->m_nValue != value)
pNode = pNode->next; if(pNode->next != NULL && pNode->next->m_nValue == value)
{
pToBeDeleted = pNode->next;
pNode->next = pNode->next->next;
}
} if(pToBeDeleted != NULL)
{
delete pToBeDeleted;
pToBeDeleted = NULL;
}
} void DestroyNode(ListNode* pNode)
{
delete pNode;
pNode = NULL;
} void reorderList(ListNode *head) {
if(NULL == head || NULL == head -> next) return; //divide
ListNode *p1 = head; ListNode* p2 = head -> next;
for(; p2 != NULL;p1 = p1 -> next, p2 = p2 -> next){
p2 = p2 -> next;
if(p2 == NULL) break;
}
ListNode* temp = p1;
p1 = p1 -> next;
temp -> next = NULL; //reverse second list
ListNode *pre = p1;
if(p1 -> next != NULL){
ListNode* p = p1 -> next;
temp = NULL;
p1 -> next = NULL;
while(p != NULL){
temp = p;
p = p -> next;
temp -> next = pre;
pre = temp;
}
}
ListNode* secHead = pre; //Insert node in second list into first list
ListNode* p = head;
ListNode* temp2 = NULL;
while(secHead != NULL){
temp = p -> next;
temp2 = secHead;
p -> next = temp2;
secHead = secHead -> next;
temp2 -> next = temp;
p = temp;
}
} int main(){
ListNode* pNode1 = CreateListNode();
ListNode* pNode2 = CreateListNode();
ListNode* pNode3 = CreateListNode();
ListNode* pNode4 = CreateListNode();
ListNode* pNode5 = CreateListNode();
ListNode* pNode6 = CreateListNode();
ListNode* pNode7 = CreateListNode(); ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode6);
ConnectListNodes(pNode4, pNode5);
ConnectListNodes(pNode5, pNode6);
ConnectListNodes(pNode6, pNode7); PrintList(pNode1);
reorderList(pNode1);
PrintList(pNode1); DestroyNode(pNode1);
DestroyNode(pNode2);
DestroyNode(pNode3);
DestroyNode(pNode4);
DestroyNode(pNode5);
DestroyNode(pNode6);
DestroyNode(pNode7); return ;
}

链表系列 - [LeetCode] 链表的交错重排L1,Ln,L2,Ln-1 ....的更多相关文章

  1. Spark2.0机器学习系列之12: 线性回归及L1、L2正则化区别与稀疏解

    概述 线性回归拟合一个因变量与一个自变量之间的线性关系y=f(x).       Spark中实现了:       (1)普通最小二乘法       (2)岭回归(L2正规化)       (3)La ...

  2. Leetcode算法系列(链表)之删除链表倒数第N个节点

    Leetcode算法系列(链表)之删除链表倒数第N个节点 难度:中等给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点.示例:给定一个链表: 1->2->3->4-&g ...

  3. Leetcode算法系列(链表)之两数相加

    Leetcode算法系列(链表)之两数相加 难度:中等给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字.如果,我们将 ...

  4. [leetcode]143. Reorder List重排链表

    Given a singly linked list L: L0→L1→…→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You may not mod ...

  5. (链表 importance) leetcode 2. Add Two Numbers

    You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...

  6. LeetCode链表解题模板

    一.通用方法以及题目分类 0.遍历链表 方法代码如下,head可以为空: ListNode* p = head; while(p!=NULL) p = p->next; 可以在这个代码上进行修改 ...

  7. LeetCode链表相加-Python<二>

    上一篇:LeetCode两数之和-Python<一> 题目:https://leetcode-cn.com/problems/add-two-numbers/description/ 给定 ...

  8. leetcode 链表类型题总结

    链表测试框架示例: // leetcodeList.cpp : 定义控制台应用程序的入口点.vs2013 测试通过 // #include "stdafx.h" #include ...

  9. leetcode: 链表2

    1. copy-list-with-random-pointer(拷贝一个带随机指针的链表) A linked list is given such that each node contains a ...

随机推荐

  1. numpy切片和布尔型索引

    numpy 标签(空格分隔): numpy 数据挖掘 切片 数组切片是原始数组的视图.这意味着数据不会被复制,视图上的任何修改都会直接反映到源数组上 In [16]: arr Out[16]: arr ...

  2. iscroll手册

    概述: 大家在日常工作中最常用的插件是什么,jQurey?Lazyload?但是这些都是在PC端,但是在移动端最常用的插件莫过于iScroll了,iScroll到底是什么东西,应该怎么用?iScrol ...

  3. js如何使浏览器允许脚本异步加载

    js如何使浏览器允许脚本异步加载 如果脚本体积很大,下载和执行的时间就会很长,因此造成浏览器堵塞,用户会感觉到浏览器“卡死”了,没有任何响应.这显然是很不好的体验,所以浏览器允许脚本异步加载,下面就是 ...

  4. 后端设置cookie写不到前端页面

    javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie("id",session.getId()); co ...

  5. iOS-加载html字符串

    NSMutableAttributedString * attrString =[[NSMutableAttributedString alloc] initWithData:[resultModel ...

  6. IIS10和Tomcat8整合

    在网上找了很久,也试了很多,都没有弄好.后来根据这个博客,做一些小修小改,终于成功了. 我是从里面的IIS与TOMCAT整合那里开始看的.第一步上面要创建一个注册表,我没有创建.我是创建了一个名为&q ...

  7. xpath教程二 ---- 通过ID和Class检索

    必备知识点 在html中,id是唯一的 在html中,class是可以多处引用的 工具 Python3版本 lxml库[优点是解析快] HTML代码块[从网络中获取或者自己杜撰一个] requests ...

  8. 如何设置windows 2003的最大远程连接数

    在Windows 2003系统上的远程桌面实际上就是终端服务,虽然远程桌面最初在Windows XP上就已经存在,但由于Windows XP的远程桌面功能,只能提供一个用户使用计算机,因此使用率并不高 ...

  9. Chromium之工程类别

    虽然有700多个project,其实有很多是不成声二进制执行文件的,他们主要是调用cygwin的环境,执行一些python的脚本. 具体这个.py文件做了哪些共工作,还要再研究,目前看到有打包一些.p ...

  10. Delphi 制作自定义数据感知控件并装入包(dpk文件)中(与DBText类似的数据感知控件)

    一.基础知识简介: 1.包的命名介绍: 包的命名没有规则,但是建议遵守包的命名约定:包的命名与包的版本相关,包的名称前面几个字符通常表示作者或公司名,也可以是控件的一个描述词,后面紧跟的Std表示运行 ...