本文共 4373 字,大约阅读时间需要 14 分钟。
Sort a linked list in O(n log n) time using constant space complexity.
/** * 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 == nullptr || head->next == nullptr) return head; ListNode * pivot = head, * small = nullptr, * large = nullptr, *sp = nullptr, *lp = nullptr; head = head->next; while(head) { if(head->val < pivot->val) { if (small == nullptr) small = head; else sp->next = head; sp = head; } else { if (large == nullptr) large = head; else lp->next = head; lp = head; } head = head->next; } if(sp) sp->next = nullptr; if(lp) lp->next = nullptr; // sort the sub list. sp = sortList(small); lp = sortList(large); // merge the sub list. if(sp) { head = sp; // seek to the last node. while(sp->next) sp = sp->next; sp->next = pivot; } else { head = pivot; } pivot->next = lp; return head; }};
if we only change the value. it will improve a some time complexity.
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {private: ListNode * partition(ListNode * head, ListNode * tail) { if(head == tail || head->next == nullptr) return head; int pivot = head->val; ListNode * slow = head, *fast = head->next; while(fast && fast != tail) { if (fast->val < pivot) { slow = slow->next; swap(slow->val, fast->val); } fast = fast->next; } // swap the pivot swap(slow->val, head->val); return slow; } void quicksort(ListNode * head, ListNode * tail) { if(head == tail || head->next == nullptr) return; ListNode * pivot = partition(head, tail); quicksort(head, pivot); quicksort(pivot->next, tail); }public: ListNode* sortList(ListNode* head) { quicksort(head, nullptr); return head; }};
if we do a non-recursive merge sort. the effeciency will be time O(NlogN), and the space with O(1).
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {private: // from head->@->@->@->null to // head->@->@->null current->@->null ListNode * cut(ListNode * head, int n) { if (head == nullptr) return head; ListNode * p = head; while(--n && p) { p = p->next; } if (p == nullptr) return nullptr; ListNode * next = p->next; // cut the current node p->next = nullptr; return next; } // merge two linklist and return the header ListNode * merge(ListNode * l, ListNode * r) { ListNode dummyHead(0); ListNode * p = &dummyHead; while(l && r) { if(l->val < r->val) { p->next = l; p = l; l = l->next; } else { p->next = r; p = r; r = r->next; } } p->next = l ? l : r; return dummyHead.next; } public: ListNode* sortList(ListNode* head) { ListNode dummyHead(0); dummyHead.next = head; int length = 0; while(head) { head = head->next; ++length; } for(int size = 1; size < length; size <<= 1) { ListNode * cur = dummyHead.next; ListNode * p = &dummyHead; while(cur) { ListNode * left = cur; ListNode * right = cut(cur, size); cur = cut(right, size); p->next = merge(left, right); // seek to the end. while(p->next) { p = p->next; } } } return dummyHead.next; }};
转载地址:http://upbg.baihongyu.com/