LeetCode刷題MEDIM篇 Sort List
阿新 • • 發佈:2019-01-09
題目
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
十分鐘思考
對於nlogn的時間複雜度,必定採用遞迴,折半,分而治之的思想。從list中間劈開,然後遞迴分割,排序後逐次合併。
但是寫程式碼,不知道具體怎麼寫,看了其他人的實現,思路是對的,自己嘗試寫一遍。尤其是從中間分割list的方法,利用快慢指標,很厲害。一定要學會這個方法,之前判斷單鏈表是否有環,也是利用快慢指標。來,自己寫一下。程式碼一次通過,沒有一點問題。總結一下:
1,拆分list的方法,利用快慢指標
2 合併兩個單鏈表,從小到大排序。首先建立一個dummy node,作為新連結串列的開頭,然後一個新的curr指標,指向加入的node
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode sortList(ListNode head) { //分而治之,從中間分開list //基準條件 if(head==null||head.next==null){ return head; } ListNode fast=head; ListNode slow=head; ListNode pre=slow; while(fast!=null&&fast.next!=null){ //記錄斷開位置 pre=slow; slow=slow.next; fast=fast.next.next; } //斷開list pre.next=null; //遞迴拆分 ListNode nodeLeft=sortList(head); ListNode nodeRight=sortList(slow); //合併list,需要依次拼接,剛開始各有一個節點,然後會有多個,依次往上合併 return merge(nodeLeft,nodeRight); } private ListNode merge(ListNode l1,ListNode l2){ //一個dummynode,一個curr指標,依次比較新增到新連結串列,長度不同,剩下的加入就可以 ListNode dummy=new ListNode(0); ListNode curr; curr=dummy; while(l1!=null&&l2!=null){ if(l1.val<l2.val){ curr.next=l1; l1=l1.next; } else{ curr.next=l2; l2=l2.next; } curr=curr.next; } //如果長度不一樣 if(l1!=null){ curr.next=l1; } if(l2!=null){ curr.next=l2; } return dummy.next; } }