143. 重排链表 - 力扣(LeetCode)
这道题非常经典,很多大厂都作为面试题。
方法一:寻找中点+翻转链表+合并链表
class Solution {
public:
void reorderList(ListNode* head) {
if (head == nullptr) {
return;
}
ListNode* mid = middleNode(head);
ListNode* l1 = head;
ListNode* l2 = mid->next;
mid->next = nullptr;
l2 = reverseList(l2);
mergeList(l1, l2);
}
ListNode* middleNode(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr != nullptr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
void mergeList(ListNode* l1, ListNode* l2) {
ListNode* l1_tmp;
ListNode* l2_tmp;
while (l1 != nullptr && l2 != nullptr) {
l1_tmp = l1->next;
l2_tmp = l2->next;
l1->next = l2;
l1 = l1_tmp;
l2->next = l1;
l2 = l2_tmp;
}
}
};
作者:力扣官方题解
链接:https://leetcode.cn/problems/reorder-list/solutions/452867/zhong-pai-lian-biao-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这种方法非常经典,一道题顶三道题,其中各种边界条件也令人很头疼。
方法二:利用栈
class Solution {
public:
void reorderList(ListNode* head) {
stack<ListNode*> stk;
ListNode* p = head;
while(p) {
stk.push(p);
p = p->next;
}
p = head;
while(!stk.empty()) {
ListNode* LastCur = stk.top();
stk.pop();
ListNode* nxt = p->next;
if(LastCur == nxt || LastCur->next == nxt) {
LastCur->next = nullptr;
break;
}
p->next = LastCur;
LastCur->next = nxt;
p = nxt;
}
}
};
其实思路是一样的,他那边的合并链表,我们主要是利用p = nxt这一条语句做到的(好好体会),反转链表是通过栈来翻转的,寻找中点是通过
找到的,同样要注意边界条件。这道题难度还是比较高的。