[LeetCode] 148. Sort List 鏈表排序
阿新 • • 發佈:2018-09-08
tco app hal get isp sel head link pac
Sort a linked list in O(n log n) time using constant space complexity.
Example 1:
Input: 4->2->1->3 Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0 Output: -1->0->3->4->5
解法:歸並排序。由於有時間和空間復雜度的要求。把鏈表從中間分開,遞歸下去,都最後兩個node時開始合並,返回上一層繼續合並,直到結束。找中間點的方法可以用快慢指針,快指針走2步,慢指針走1步。也可以求出鏈表長度,再分開鏈表。
Java:
public class Solution { public ListNode sortList(ListNode head) { if (head == null || head.next == null) return head; // step 1. cut the list to two halves ListNode prev = null, slow = head, fast = head; while (fast != null && fast.next != null) { prev = slow; slow = slow.next; fast = fast.next.next; } prev.next = null; // step 2. sort each half ListNode l1 = sortList(head); ListNode l2 = sortList(slow); // step 3. merge l1 and l2 return merge(l1, l2); } ListNode merge(ListNode l1, ListNode l2) { ListNode l = new ListNode(0), p = l; while (l1 != null && l2 != null) { if (l1.val < l2.val) { p.next = l1; l1 = l1.next; } else { p.next = l2; l2 = l2.next; } p = p.next; } if (l1 != null) p.next = l1; if (l2 != null) p.next = l2; return l.next; } }
Python:
class Solution(object): def merge(self, h1, h2): dummy = tail = ListNode(None) while h1 and h2: if h1.val < h2.val: tail.next, tail, h1 = h1, h1, h1.next else: tail.next, tail, h2 = h2, h2, h2.next tail.next = h1 or h2 return dummy.next def sortList(self, head): if not head or not head.next: return head pre, slow, fast = None, head, head while fast and fast.next: pre, slow, fast = slow, slow.next, fast.next.next pre.next = None return self.merge(*map(self.sortList, (head, slow)))
C++:
class Solution { public: ListNode *sortList(ListNode *head) { if(!head || !(head->next)) return head; //get the linked list‘s length ListNode* cur = head; int length = 0; while(cur){ length++; cur = cur->next; } ListNode dummy(0); dummy.next = head; ListNode *left, *right, *tail; for(int step = 1; step < length; step <<= 1){ cur = dummy.next; tail = &dummy; while(cur){ left = cur; right = split(left, step); cur = split(right,step); tail = merge(left, right, tail); } } return dummy.next; } private: /** * Divide the linked list into two lists, * while the first list contains first n ndoes * return the second list‘s head */ ListNode* split(ListNode *head, int n){ //if(!head) return NULL; for(int i = 1; head && i < n; i++) head = head->next; if(!head) return NULL; ListNode *second = head->next; head->next = NULL; return second; } /** * merge the two sorted linked list l1 and l2, * then append the merged sorted linked list to the node head * return the tail of the merged sorted linked list */ ListNode* merge(ListNode* l1, ListNode* l2, ListNode* head){ ListNode *cur = head; while(l1 && l2){ if(l1->val > l2->val){ cur->next = l2; cur = l2; l2 = l2->next; } else{ cur->next = l1; cur = l1; l1 = l1->next; } } cur->next = (l1 ? l1 : l2); while(cur->next) cur = cur->next; return cur; } };
[LeetCode] 148. Sort List 鏈表排序