148.Sort List---鏈表排序(冒泡、歸併)

題目連接ide

題目大意:對鏈表進行排序,要求時間複雜度是o(nlgn)。spa

法一:冒泡,不交換結點,而交換結點中的數值。超時了。代碼以下:指針

 1     public ListNode sortList(ListNode head) {
 2         if(head == null || head.next == null) {
 3             return head;
 4         }
 5         ListNode cur = null, tail = null;
 6         cur = head;
 7         while(cur.next != tail) {
 8             while(cur.next != tail) {
 9                 //其實這裏交換的是兩個相鄰結點的值,並無交換兩個結點指針
10                 if(cur.val > cur.next.val) {
11                     int tmp = cur.val;
12                     cur.val = cur.next.val;
13                     cur.next.val = tmp;
14                 }
15                 cur = cur.next;
16             }
17             //每一趟排序都會把一個相對最大的數排到最後一個,因此這裏要將tail置爲cur,而不是一直是null
18             tail = cur;//下一次遍歷的尾結點是當前結點
19             //每一趟都再次從頭開始遍歷
20             cur = head;//遍歷起始結點重置爲頭結點
21         }
22         return head;
23     }
View Code

法二:歸併,交換結點,利用尾插,誰小誰放在前面。代碼以下(耗時7ms):code

 1     public ListNode sortList(ListNode head) {
 2         if(head == null || head.next == null) {
 3             return head;
 4         }
 5         //劃分紅兩個鏈表,由快慢指針獲得。
 6         //最終slow會指向第二個鏈表的起始位置,fast會指向第二個鏈表的末尾,pre會指向第一個鏈表的末尾
 7         ListNode pre = null, slow = head, fast = head;
 8         while(fast != null && fast.next != null) {
 9             pre = slow;
10             slow = slow.next;
11             fast = fast.next.next;
12         }
13         //第一個鏈表的終結
14         pre.next = null;
15         //分別對兩個鏈表進行排序
16         //head是第一個鏈表的頭,slow是第二個鏈表的頭
17         ListNode l1 = sortList(head);
18         ListNode l2 = sortList(slow);
19         //歸併l1和l2
20         return merge(l1, l2);
21     }
22     private static ListNode merge(ListNode l1, ListNode l2) {
23         //l頭節點初始化爲0,返回的時候返回l.next便可,即不帶頭結點的指針
24         ListNode l = new ListNode(0), p = l;
25         while(l1 != null && l2 != null) {
26             //尾插
27             if(l1.val < l2.val) {
28                 p.next = l1;
29                 l1 = l1.next;
30             }
31             else {
32                 p.next = l2;
33                 l2 = l2.next;
34             }
35             p = p.next;
36         }
37         //若是還有結點,則直接放在其後便可
38         if(l1 != null) {
39             p.next = l1;
40         }
41         if(l2 != null) {
42             p.next = l2;
43         }
44         return l.next;
45     }
View Code
相關文章
相關標籤/搜索