难度:中等。
标签:栈,递归,链表,双指针。
先使用快慢指针找到链表的分界点处,将分界点及以后的链表反转。
然后将两个链表合并起来。
注意第52行,需要将前面的链表尾节点指向nullptr,否则他之前指向的是后面链表的第一个节点,该节点已经被反转到后面链表的最后一个了。如果不加上这句,会报以下错:
AddressSanitizer: heap-use-after-free
正确解法:
/**
* 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 == nullptr)return;
ListNode* node1 = head;
ListNode* slow = head->next, *fast = head->next;
while(fast != nullptr && fast->next != nullptr){
slow = slow->next;
fast = fast->next->next;
}
ListNode* node2 = nullptr, *temp = nullptr;
while(slow != nullptr){
if(slow->next == nullptr){
slow->next = temp;
node2 = slow;
break;
}
else if(slow->next->next == nullptr){
node2 = slow->next;
slow->next->next = slow;
slow->next = temp;
break;
}
ListNode* next_node = slow->next;
ListNode* next_next_node = next_node->next;
next_node->next = slow;
slow->next = temp;
slow = next_next_node;
temp = next_node;
}
int i = 0;
while(node1 != nullptr && node2 != nullptr){
if(i % 2 == 0){
ListNode* next1 = node1->next;
node1->next = node2;
node1 = next1;
}
else{
ListNode* next2 = node2->next;
node2->next = node1;
if(next2 == nullptr)node1->next = nullptr;
node2 = next2;
}
i++;
}
}
};
结果: