在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
1. 利用递归的归并排序,自顶向下递归解决问题。
class Solution { public: ListNode* sortList(ListNode* head) { if(!head) return NULL; int length = 0; ListNode* p = head; if(head->next == NULL) return head; while(p){ length++; p = p->next; } int mid = length / 2; //从中点分割链表 ListNode* later = cut(head, mid); //前边部分的链表 ListNode* fore = sortList(head); //后边部分的链表 ListNode* late = sortList(later); ListNode *result = merge(fore, late); return result; } ListNode* cut(ListNode* head, int n){ auto p = head; int index = 0; while(p){ index++; if(index == n){ break; } p = p->next; } auto tmp = p->next; p->next = NULL; return tmp; } ListNode* merge(ListNode* head1, ListNode* head2){ ListNode dummyNode = ListNode(0); //牵引结点 ListNode* p = &dummyNode; while(head1||head2){ if(!head1){ p->next = new ListNode(head2->val); p = p->next; head2 = head2->next; } else if(!head2){ p->next = new ListNode(head1->val); p = p->next; head1 = head1->next; }else if(head1->val < head2->val){ p->next = new ListNode(head1->val); p = p->next; head1 = head1->next; } else { p->next = new ListNode(head2->val); p = p->next; head2 = head2->next; } //if(!head1 && !head2){}} } return dummyNode.next; } } ;
自底部向上,两两相邻链表相融合。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* sortList(ListNode* head) { if(!head) return NULL; ListNode dummyHead(0); dummyHead.next = head; ListNode* p = head; int len = 0; while(p){ len++; p = p->next; } //size:两两合并的链表长度 for(int size = 1; size < len; size <<= 1){ auto cur = dummyHead.next; //当前结点 auto tail = &dummyHead; //尾部结点 while(cur){ auto left = cur; auto right = cut(left, size); cur = cut(right, size); tail->next = merge(left, right); //两链表相连 while(tail->next){ tail = tail->next; } } } return dummyHead.next; } ListNode* cut(ListNode* head, int n){ auto p = head; int index = 0; while(p&&--n){ p = p->next; } if(!p) return nullptr; auto next = p->next; p->next = NULL; return next; } ListNode* merge(ListNode* head1, ListNode* head2){ ListNode dummyNode = ListNode(0); //牵引结点 ListNode* p = &dummyNode; while(head1||head2){ if(!head1){ p->next = new ListNode(head2->val); p = p->next; head2 = head2->next; } else if(!head2){ p->next = new ListNode(head1->val); p = p->next; head1 = head1->next; }else if(head1->val < head2->val){ p->next = new ListNode(head1->val); p = p->next; head1 = head1->next; } else { p->next = new ListNode(head2->val); p = p->next; head2 = head2->next; } //if(!head1 && !head2){}} } return dummyNode.next; } };