【leetcode】143. Reorder List

题目说明

https://leetcode-cn.com/problems/reorder-list/description/
给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…

解法1

首先利用快慢指针找到链表中间结点mid,然后从head遍历到mid,遍历时,将对应的尾部结点插入到当前结点之后。
找尾部对应结点时,从mid遍历到尾部找到对应的尾部结点。整个过程进行了双重循环,时间复杂度较高。还是推荐解法2。
时间复杂度:O(n^2)

/*
* 时间复杂度:O(n^2)
* 先找到中间结点mid
* 从head遍历到mid,遍历时,将对应的尾部结点插入到当前结点之后
/
void reorderList(ListNode
head) {
if (head == NULL || head->next == NULL)
return;
ListNode *slow = head;
ListNode *fast = head;

while(fast->next && fast->next->next){
slow = slow->next;
fast = fast->next->next;
}
ListNode *mid = slow;
ListNode *pre = head;
ListNode *lastpre = NULL;
ListNode *tmp = NULL;
ListNode *moveNode = NULL;

while(pre != mid){
lastpre = mid;
while(lastpre->next && lastpre->next->next)//找到尾部结点前一个结点
lastpre = lastpre->next;
moveNode = lastpre->next;
tmp = pre->next;
pre->next = moveNode;
moveNode->next = tmp;
lastpre->next = NULL;
pre = tmp;
}
return ;
}

解法2

首先利用快慢指针找到链表中间结点mid,然后将之后的链表进行反转。
然后同时遍历正向与反向链表,将反向链表对应结点插入到正向链表结点之后。
这样遍历了三次链表,时间复杂度:O(n)。

/*
* 时间复杂度:O(n)
* 找到中结点后,将之后的链表进行反转
* 然后从两个链表头结点(即原链表的头尾)开始遍历
* 将反向链表的相应结点插入到正向链表之后
/
void reorderList(ListNode
head) {
if (head == NULL || head->next == NULL)
return;
ListNode *slow = head;
ListNode *fast = head;

//找到中间结点
while(fast->next && fast->next->next){
slow = slow->next;
fast = fast->next->next;
}
ListNode *mid = slow;
ListNode *pre = NULL;
ListNode *last = mid->next;
ListNode *tmp = NULL;
ListNode *tmp1 = NULL;

//中结点之后置为空,正向链表尾部指向NULL
mid->next = NULL;
//反转中结点之后的链表,反向链表尾部指向初始的pre即NULL
while(last){
tmp = last->next;
last->next = pre;
pre = last;
last = tmp;
}

ListNode *headNode = head;
ListNode *tailNode = pre;

//同时遍历正向与反向链表,将反向链表对应结点插入到正向链表结点之后
while(headNode && tailNode){
tmp = headNode->next;
tmp1 = tailNode->next;
headNode->next = tailNode;
tailNode->next = tmp;
headNode = tmp;
tailNode = tmp1;
}
return ;
}

posted @ 2018-09-06 01:07  JESSET  阅读(149)  评论(0)    收藏  举报