题目143:Reorder List
Reorder List Total Accepted: 46551 Total Submissions: 221280 My Submissions Question Solution
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}.
思路分析:
先用快慢指针找到链表的中点,将链表的后半部分转置,转置后合并这两个半个链表。
常用到的操作:
1. 快慢指针找链表中点;
2. 转置一个链表(递归和非递归实现);
3. 链表的插入、删除
class Solution {
public:
ListNode *reverse(ListNode* head) {
if (0 == head || 0 == head->next)
return head;
ListNode *pre, *cur;
pre = 0;
cur = head;
while (cur) {
ListNode *pnext = cur->next;
cur->next = pre;
pre = cur;
cur = pnext;
}
return pre;
}
void reorderList(ListNode* head) {
if (head == 0 || head->next == 0)
return;
ListNode *fast, *slow, *mid;
fast = head;
slow = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
/* 链表的一半是slow的next */
mid = slow->next;
slow->next = 0;
ListNode *reverse_head, *merge_head;
reverse_head = reverse(mid);
fast = head;
/* 可以这么合并oo */
while (fast && reverse_head) {
ListNode *temp = reverse_head->next;
reverse_head->next = fast->next;
fast->next = reverse_head;
fast = reverse_head->next;
reverse_head = temp;
}
/* 这里两个子链表是转置的子链表空,则合并就结束了。 */
}
};