难度:中等。
标签:链表,双指针,分治,排序,归并排序。
归并排序,注意处理一段链表,要注意这一段链表的前后节点的连接。
/**
* 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 {
pair<ListNode*, ListNode*> merge(ListNode* A, int lenA, ListNode* B, int lenB){
ListNode* head = nullptr;
ListNode* cur = nullptr;
int a = 0, b = 0;
while(a < lenA && b < lenB){
if(A->val < B->val){
if(head == nullptr){
head = new ListNode(A->val);
cur = head;
}
else{
cur->next = new ListNode(A->val);
cur = cur->next;
}
a++;
A = A->next;
}
else{
if(head == nullptr){
head = new ListNode(B->val);
cur = head;
}
else{
cur->next = new ListNode(B->val);
cur = cur->next;
}
b++;
B = B->next;
}
}
while(a < lenA){
cur->next = A;
A = A->next;
cur = cur->next;
a++;
}
while(b < lenB){
cur->next = B;
B = B->next;
cur = cur->next;
b++;
}
return {head, cur};
}
ListNode* mergeSort(ListNode* nodeA, int n, ListNode* pre, ListNode* next){
if(n > 1){
ListNode* nodeB = nodeA;
ListNode* tailA = nodeA;
int part1 = n / 2, part2 = n - part1;
for(int i = 0; i < part1; ++i){
tailA = nodeB;
nodeB = nodeB->next;
}
ListNode* headA = mergeSort(nodeA, part1, pre, nodeB);
ListNode* headB = mergeSort(nodeB, part2, tailA, next);
auto pair3 = merge(headA, part1, headB, part2);
ListNode* head = pair3.first, *tail = pair3.second;
if(pre != nullptr)pre->next = head;
tail->next = next;
return head;
}
return nodeA;
}
public:
ListNode* sortList(ListNode* head) {
int len = 0;
ListNode* temp = head;
while(temp != nullptr){
len++;
temp = temp->next;
}
return mergeSort(head, len, nullptr, nullptr);
}
};
结果:
怎么这么慢呢。
看下题解,优化一下。
题解并没有使用长度来标定一段链表,而是将一段链表指向的下一个节点置为nullptr,然后对两个链表进行归并排序。
正确解法:
/**
* 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 {
ListNode* merge(ListNode* A, ListNode* B){
ListNode* head = nullptr;
ListNode* cur = nullptr;
while(A != nullptr && B != nullptr){
if(A->val < B->val){
if(head == nullptr){
head = A;
cur = head;
}
else{
cur->next = A;
cur = cur->next;
}
A = A->next;
}
else{
if(head == nullptr){
head = B;
cur = head;
}
else{
cur->next = B;
cur = cur->next;
}
B = B->next;
}
}
if(A != nullptr){
cur->next = A;
}
if(B != nullptr){
cur->next = B;
}
return head;
}
ListNode* mergeSort(ListNode* head, ListNode* tail){
if(head == nullptr){
return head;
}
if(head->next == tail){
head->next = nullptr;
return head;
}
ListNode* mid = head, *fast = head;
while(fast != tail && fast->next != tail){
mid = mid->next;
fast = fast->next->next;
}
ListNode* head1 = mergeSort(head, mid);
ListNode* head2 = mergeSort(mid, tail);
ListNode* newHead = merge(head1, head2);
return newHead;
}
public:
ListNode* sortList(ListNode* head) {
return mergeSort(head, nullptr);
}
};
结果: