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 modify the values in the list’s nodes, only nodes itself may be changed.
Example 1:
Given 1->2->3->4, reorder it to 1->4->2->3.
Example 2:
Given 1->2->3->4->5, reorder it to 1->5->2->4->3.
grandyang: http://www.cnblogs.com/grandyang/p/4254860.html
方法1:
思路:用快慢指针找到链表中点,断开并反转后半段。将两个链表间隔融合。
易错点:
- fast/slow 的方法从prev起找到的是左中卫,从head起找到的是右中卫。一般来说左中卫比较有用。
- if (!head || !head->next || !head->next->next) return:虽然没什么必要,但是避免思考超级edge的case。比如只有一个数。
// null 1 -> 2 -> 3 -> 4 -> 5
// prev slow mid fast
// null 1 -> 2 3 -> 4 -> 5
// prev slow last next
// 1 -> 2 null <- 3 4 -> 5
// prev last next
// 1 -> 2 null <- 3 4 -> 5
// prev last next
// 1 -> 2 null <- 3 <- 4 5
// prev last next
// 1 -> 2 null <- 3 <- 4 <- 5
// head prev last
// 1 -> 2
// head next
// 5 -> 4 -> 3
// prev
class Solution {
public:
void reorderList(ListNode *head) {
if (!head || !head->next || !head->next->next) return;
ListNode *fast = head, *slow = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
ListNode *mid = slow->next;
cout << mid -> val ;
slow->next = NULL;
ListNode *last = mid, *pre = NULL;
while (last) {
ListNode *next = last->next;
last->next = pre;
pre = last;
last = next;
}
while (head && pre) {
ListNode *next = head->next;
head->next = pre;
pre = pre->next;
head->next->next = next;
head = next;
}
}
};
class Solution {
public:
void reorderList(ListNode *head) {
ListNode* newHead1 = new ListNode(-1), * slow = newHead1, * fast = newHead1;
newHead1 -> next = head;
while (fast && fast -> next) {
slow = slow -> next;
fast = fast -> next;
fast = fast -> next;
}
// cut the link between prev and slow
ListNode* newHead2 = slow -> next;
slow -> next = nullptr;
// reverse newHead2
ListNode* prev = nullptr, * cur = newHead2;
while (cur) {
ListNode* tmp = cur -> next;
cur -> next = prev;
prev = cur;
cur = tmp;
}
// merge two list
newHead2 = prev;
// newhead2存在,head一定存在,其实不用查head。
while (head && newHead2) {
ListNode* tmp = head -> next;
head -> next = newHead2;
newHead2 = newHead2 -> next;
head -> next -> next = tmp;
head = tmp;
}
return;
}
};
方法2: stack
易错点:
最后断开栈顶,否则会闭环
class Solution {
public:
void reorderList(ListNode *head) {
if (!head || !head->next || !head->next->next) return;
stack<ListNode*> st;
ListNode *cur = head;
while (cur) {
st.push(cur);
cur = cur->next;
}
int cnt = ((int)st.size() - 1) / 2;
cur = head;
while (cnt-- > 0) {
auto t = st.top(); st.pop();
ListNode *next = cur->next;
cur->next = t;
t->next = next;
cur = next;
}
st.top()->next = NULL;
}
};