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 must do this in-place without altering the nodes’ values.
For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.
分析:这道题的思路首先用快慢指针找到链表的中点,然后将此链表分成两部分,再将后面的链表逆序,最后将两部分合并即可。
第一种解法
class Solution
{
public:
void reorderList(ListNode* head)
{
if(head == nullptr || head->next == nullptr) return;
ListNode *fastp = head, *lowp = head, *tail = nullptr;
while(fastp != nullptr && fastp->next != nullptr)
{
tail = lowp;
fastp = fastp->next->next;
lowp = lowp->next; //实际上找到的中点,当链表长度为奇数时处于中点,偶数时处于L/2+1位置
}
tail->next = nullptr; //分成一半 前半部分在奇数时比后半部分小1
reverseList(lowp);
fastp = head;
tail = nullptr;
while(fastp != nullptr)
{
ListNode *tmp = lowp->next;
lowp->next = fastp->next;
fastp->next = lowp;
tail = lowp; //奇数时特例,奇数时前半段链表比后半边链表少一个元素
fastp = lowp->next;
lowp = tmp;
}
if(lowp != nullptr)
tail->next = lowp; //把最后一个元素,即中间那个元素添加到链表的最后
}
void reverseList(ListNode* &head)
{
if(head == nullptr || head->next == nullptr) return;
ListNode *pre = head, *p = pre->next;
while(p != nullptr)
{
ListNode *tmp = p->next;
p->next = pre;
pre = p;
p = tmp;
}
head->next = nullptr;
head = pre;
}
};
第二种解法
class Solution
{
public:
void reorderList(ListNode* head)
{
ListNode *mid = findMid(head);
ListNOde *right = reverseList(mid);
ListNode *left = head;
while(right && right->next) //最后一个元素没有进行连接,是因为left最后一个元素本来就连着right的最后一个元素
{
ListNode *target = right;
right = right->next;
target->next = left->next;
left->next = target;
left = target->next;
}
}
ListNode* findMid(ListNode* head)
{
ListNode *fast = head;
ListNode *slow = head;
while(fast && fast->next)
{
fast = fast->next->next
slow = slow->next;
}
return slow
}
ListNode* reverseList(ListNode *head)
{
if(!head || !head->next) return head;
ListNode *pre = head, *cur = head->next;
while(cur)
{
ListNode *temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
head->next = nullptr;
return pre;
}
};
第三种解法
public class Solution {
public void reorderList(ListNode head) {
if(head == null || head.next == null) return;
ListNode slow = head;
ListNode fast = head;
while(fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
ListNode mid = slow.next;
ListNode last = mid;
ListNode pre = null;
while(last != null){
ListNode next = last.next;
last.next = pre;
pre = last;
last = next;
}
slow.next = null;
while(head != null && pre != null){
ListNode next1 = head.next;
head.next = pre;
pre = pre.next;
head.next.next = next1;
head = next1;
}
}
}