问题描述:
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.
源码:
空间比较差的那种,用了很多额外的变量。思路是先按照中间点分成两个链,然后把第二个反转,最后合并到第一个。
时间99%,空间只有可怜的5%。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
void reorderList(ListNode* head) {
if (!head || !head->next || !head->next->next) return;
ListNode* p1 = head, *p2 = head;
// 切割
while(p2->next && p2->next->next){
p1 = p1->next;
p2 = p2->next->next;
}
p2 = p1->next;
p1->next = NULL;
// 翻转p2
p1 = p2;
ListNode *pre = NULL;
while(p1){
ListNode* next = p1->next;
p1->next = pre;
pre = p1;
p1 = next;
}
// p2插入head
while(head && pre){
ListNode *next = head->next;
head->next = pre;
pre = pre->next;
head->next->next = next;
head = next;
}
}
};
还有一种用栈解决,栈就可以起到反转的作用,但是只反转后一部分。
这种方法思路清晰,但其实空间损耗更大,需要一个栈,时间98%,空间5%。
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 mid = (int(st.size()) - 1) / 2;
cur = head;
while(mid--){
auto tmp = st.top();
st.pop();
ListNode* next = cur->next;
cur->next = tmp;
tmp->next = next;
cur = next;
}
st.top()->next = NULL;
}
};