链表系列 - [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 ...
随机推荐
- 线性代数之——对角化和 A 的幂
利用特征向量的属性,矩阵 \(A\) 可以变成一个对角化矩阵 \(\Lambda\). 1. 对角化 假设一个 \(n×n\) 的矩阵 \(A\) 有 \(n\) 个线性不相关的特征向量 \(x_1, ...
- Educational Codeforces Round 32 Problem 888C - K-Dominant Character
1) Link to the problem: http://codeforces.com/contest/888/problem/C 2) Description: You are given a ...
- 由一个hash字符串生成多个子hash字符串
通过存储一个head hash,然后把子hash放到网络中 当然,也可以像默克尔树那样的,生成多级的子hash ,可以通过规则配置不同的hash 生成方式.倒置的默克尔树 我有一个文件,然后我把她分隔 ...
- 在mesh client示例中加入spi_slave接口(without IDE)
在mesh client示例中加入spi_slave接口(without IDE) 主要是理解cmake构建的过程,然后修改工程中的inlcude路径及c源文件. 1. 解压mesh_sdk unzi ...
- Hyperledger fablic 1.0 在centos7环境下的安装与部署和动态增加节点
Hyperledger fablic 1.0 在centos7环境下的安装与部署和动态增加节点 一.安装docker 执行代码如下: curl -sSL https://get.daocloud.io ...
- KVM存储虚拟化---玩转openstack
KVM 的存储虚拟化是通过存储池(Storage Pool)和卷(Volume)来管理的. Storage Pool 是宿主机上可以看到的一片存储空间,可以是多种类型,后面会详细讨论.Volume 是 ...
- maven 教程二 深入
一:编写POM <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w ...
- 业务迁移---redis
以前也没怎么搞过redis 只知道他是一个nosql数据库很强大,这次迁移用到了~ 正好熟练一下并记录过程,还挺繁琐.. 记录一下在学习中的几个问题,总结加深一下印象,有可能会漏掉或者有误差的地方~ ...
- 软件测试基础-Homework1
The error was in my graduate work which was about game development.I broadcast some messages to the ...
- Thunder团队第一次Scrum会议
Scrum会议1 小组名称:Thunder 项目名称:待定 参会成员: 王航(Master):http://www.cnblogs.com/wangh013/ 李传康:http://www.cnblo ...