链表系列 - [LeetCode] 链表的交错重排L1,Ln,L2,Ln-1 ....
其实一开始并没有想到时间上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 ....的更多相关文章
- Spark2.0机器学习系列之12: 线性回归及L1、L2正则化区别与稀疏解
概述 线性回归拟合一个因变量与一个自变量之间的线性关系y=f(x). Spark中实现了: (1)普通最小二乘法 (2)岭回归(L2正规化) (3)La ...
- Leetcode算法系列(链表)之删除链表倒数第N个节点
Leetcode算法系列(链表)之删除链表倒数第N个节点 难度:中等给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点.示例:给定一个链表: 1->2->3->4-&g ...
- Leetcode算法系列(链表)之两数相加
Leetcode算法系列(链表)之两数相加 难度:中等给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字.如果,我们将 ...
- [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 ...
- (链表 importance) leetcode 2. Add Two Numbers
You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...
- LeetCode链表解题模板
一.通用方法以及题目分类 0.遍历链表 方法代码如下,head可以为空: ListNode* p = head; while(p!=NULL) p = p->next; 可以在这个代码上进行修改 ...
- LeetCode链表相加-Python<二>
上一篇:LeetCode两数之和-Python<一> 题目:https://leetcode-cn.com/problems/add-two-numbers/description/ 给定 ...
- leetcode 链表类型题总结
链表测试框架示例: // leetcodeList.cpp : 定义控制台应用程序的入口点.vs2013 测试通过 // #include "stdafx.h" #include ...
- leetcode: 链表2
1. copy-list-with-random-pointer(拷贝一个带随机指针的链表) A linked list is given such that each node contains a ...
随机推荐
- RL_Learning
Key Concepts in RL 标签(空格分隔): RL_learning OpenAI Spinning Up原址 states and observations (状态和观测) action ...
- 使用树莓派实现(山寨)高清视频叠加(HDMI OSD)
项目需要在HDMI上叠加一些字符包括汉字和数值,要求不能使用台式机,本身也没有HDMI采集卡驱动开发能力,所以通过海思的HDMI编码器将HDMI编码为h.264网络视频流,然后通过树莓派解码显示,做字 ...
- 1.安装CDH5.12.x
安装方式安装前准备安装步骤安装过程修改/etc/hosts设置ssh 互信修改linux 系统设置安装JDK1.8安装python2.7安装mysql/postgreysql数据库安装ntp设置本地y ...
- nginx配置和网站的部署
环境: CentOS Linux release 7.3.1611 (Core) nginx version: nginx/1.13.4 PHP 5.4.16 (cli) (built: Nov 6 ...
- (三)java字符串
不可变字符串 Java没有字符串类型,而是提供了一个预定义类String. java中的字符串是不可变字符串,因此无法更改某一个字符串变量的内容. 优点:编译器可以让字符串共享.当复制一个字符串时,原 ...
- MFC修改视图CView的背景颜色
(1) 在CYournameView(就是你的视图类,以下以CDrawLineView为例)添加了一个背景颜色变量 COLORREF m_bgcolor; (2)修改这个函数: BOOL CDrawL ...
- iOS单利创建的方法
我们在使用单例的时候有两种方法@synchronized,GCD,往往人们使用@synchronized,但是推荐使用GCD: 第一种(@synchronized): + (id)sharedInst ...
- ResultSet 可滚动性和可更新性
JDBC 2.0 API 为结果集增加了两个新的基本能力:可滚动性和可更新性,我想肯定满足了你的要求.在滚动结果集中可用的方法有: rs.previous();//向前滚动 rs.next();//向 ...
- AutoHotKey 快速入门
AutoHotKey 是一个免费的键盘宏程序,可以用于配置键盘快捷键.鼠标事件 以及摇杆事件,还可以在输入文本的时候对文本进行扩展(自动补全) 第一个脚本 新建文件test.ahk并输入以下内容: ^ ...
- SQL SERVER 存储过程中SELECT 返回值如何赋值给变量
今天在处理一个问题时,使用到一个存储过程,是用于更新并获取最新ID的.在使用过程中,需要获取到这个ID并赋值给变量,结果用EXEC @ID = 存储过程的方式获取失败了.具体情况如下: 为了还原整个情 ...