方法一找到中间后,右半区压入栈中,然后将两部分合并
class Solution {
public:
void reorderList(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
ListNode* mid;
stack<ListNode*> st;
while (fast->next != NULL && fast->next->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
mid = slow;
slow = slow->next;
mid->next = NULL;
while (slow != NULL) {
st.push(slow);
slow = slow->next;
}
while (head != NULL) {
ListNode* nex = head->next;
if (!st.empty()) {
ListNode* ss = st.top();
st.pop();
ss->next = nex;
head->next = ss;
head = head->next;
head = head->next;
}
else {
head = head->next;
}
}
}
};
值得注意的点就是两部分链表合并时出现的问题,采用弹出一个栈中的节点,就将他的前驱和后继都搞定,此时head的位置需要后移两个位置,才能到达新的节点。当栈中元素全部弹出,那么只需将head后移,就可以跳出循环。此处的解决方法,真的烦了我一整天。
方法二 将后半区原地反转,空间复杂度O(1)
class Solution {
public:
void reorderList(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast->next != NULL && fast->next->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
ListNode* mid = slow;
ListNode* cur = slow->next;
mid->next = NULL;
ListNode* next = NULL;
ListNode* newhead = NULL;
while (cur != NULL) {
next = cur->next;
cur->next = newhead;
newhead = cur;
cur = next;
}
while (head != NULL && newhead != NULL) {
ListNode* temp1 = head->next;
ListNode* temp2 = newhead->next;
head->next = newhead;
head = temp1;
newhead->next = head;
newhead = temp2;
}
}
};