zoukankan      html  css  js  c++  java
  • *Sort List

    Sort a linked list in O(n log n) time using constant space complexity.

      1 /**
      2  * 本代码由九章算法编辑提供。没有版权欢迎转发。
      3  * - 九章算法致力于帮助更多中国人找到好的工作,教师团队均来自硅谷和国内的一线大公司在职工程师。
      4  * - 现有的面试培训课程包括:九章算法班,系统设计班,BAT国内班
      5  * - 更多详情请见官方网站:http://www.jiuzhang.com/
      6  */
      7 
      8 // version 1: Merge Sort
      9 public class Solution {            
     10     private ListNode findMiddle(ListNode head) {
     11         ListNode slow = head, fast = head.next;
     12         while (fast != null && fast.next != null) {
     13             fast = fast.next.next;
     14             slow = slow.next;
     15         }
     16         return slow;
     17     }    
     18 
     19     private ListNode merge(ListNode head1, ListNode head2) {
     20         ListNode dummy = new ListNode(0);
     21         ListNode tail = dummy;
     22         while (head1 != null && head2 != null) {
     23             if (head1.val < head2.val) {
     24                 tail.next = head1;
     25                 head1 = head1.next;
     26             } else {
     27                 tail.next = head2;
     28                 head2 = head2.next;
     29             }
     30             tail = tail.next;
     31         }
     32         if (head1 != null) {
     33             tail.next = head1;
     34         } else {
     35             tail.next = head2;
     36         }
     37 
     38         return dummy.next;
     39     }
     40 
     41     public ListNode sortList(ListNode head) {
     42         if (head == null || head.next == null) {
     43             return head;
     44         }
     45 
     46         ListNode mid = findMiddle(head);
     47 
     48         ListNode right = sortList(mid.next);
     49         mid.next = null;
     50         ListNode left = sortList(head);
     51 
     52         return merge(left, right);
     53     }
     54 }
     55 
     56 // version 2: Quick Sort 1
     57 public class Solution {
     58     public ListNode sortList(ListNode head) {
     59         if (head == null || head.next == null) {
     60             return head;
     61         }
     62         
     63         ListNode mid = findMedian(head); // O(n)
     64         
     65         ListNode leftDummy = new ListNode(0), leftTail = leftDummy;
     66         ListNode rightDummy = new ListNode(0), rightTail = rightDummy;
     67         ListNode middleDummy = new ListNode(0), middleTail = middleDummy;
     68         while (head != null) {
     69             if (head.val < mid.val) {
     70                 leftTail.next = head;
     71                 leftTail = head;
     72             } else if (head.val > mid.val) {
     73                 rightTail.next = head;
     74                 rightTail = head;
     75             } else {
     76                 middleTail.next = head;
     77                 middleTail = head;
     78             }
     79             head = head.next;
     80         }
     81         
     82         leftTail.next = null;
     83         middleTail.next = null;
     84         rightTail.next = null;
     85         
     86         ListNode left = sortList(leftDummy.next);
     87         ListNode right = sortList(rightDummy.next);
     88         
     89         return concat(left, middleDummy.next, right);
     90     }
     91     
     92     private ListNode findMedian(ListNode head) {
     93         ListNode slow = head, fast = head.next;
     94         while (fast != null && fast.next != null) {
     95             slow = slow.next;
     96             fast = fast.next.next;
     97         }
     98         return slow;
     99     }
    100     
    101     private ListNode concat(ListNode left, ListNode middle, ListNode right) {
    102         ListNode dummy = new ListNode(0), tail = dummy;
    103         
    104         tail.next = left; tail = getTail(tail);
    105         tail.next = middle; tail = getTail(tail);
    106         tail.next = right; tail = getTail(tail);
    107         return dummy.next;
    108     }
    109     
    110     private ListNode getTail(ListNode head) {
    111         if (head == null) {
    112            return null;
    113         } 
    114        
    115         while (head.next != null) {
    116             head = head.next;
    117         }
    118         return head;
    119     }
    120 }
    121 
    122 // version 3: Quick Sort 2
    123 /**
    124  * Definition for ListNode.
    125  * public class ListNode {
    126  *     int val;
    127  *     ListNode next;
    128  *     ListNode(int val) {
    129  *         this.val = val;
    130  *         this.next = null;
    131  *     }
    132  * }
    133  */ 
    134 class Pair {
    135     public ListNode first, second; 
    136     public Pair(ListNode first, ListNode second) {
    137         this.first = first;
    138         this.second = second;
    139     }
    140 }
    141 
    142 public class Solution {
    143     /**
    144      * @param head: The head of linked list.
    145      * @return: You should return the head of the sorted linked list,
    146                     using constant space complexity.
    147      */
    148     public ListNode sortList(ListNode head) {
    149         if (head == null || head.next == null) {
    150             return head;
    151         }
    152         
    153         ListNode mid = findMedian(head); // O(n)
    154         Pair pair = partition(head, mid.val); // O(n)
    155         
    156         ListNode left = sortList(pair.first);
    157         ListNode right = sortList(pair.second);
    158         
    159         getTail(left).next = right; // O(n)
    160         
    161         return left;
    162     }
    163     
    164     // 1->2->3 return 2
    165     // 1->2 return 1
    166     private ListNode findMedian(ListNode head) {
    167         ListNode slow = head, fast = head.next;
    168         while (fast != null && fast.next != null) {
    169             slow = slow.next;
    170             fast = fast.next.next;
    171         }
    172         return slow;
    173     }
    174     
    175     // < value in the left, > value in the right
    176     private Pair partition(ListNode head, int value) {
    177         ListNode leftDummy = new ListNode(0), leftTail = leftDummy;
    178         ListNode rightDummy = new ListNode(0), rightTail = rightDummy;
    179         ListNode equalDummy = new ListNode(0), equalTail = equalDummy;
    180         while (head != null) {
    181             if (head.val < value) {
    182                 leftTail.next = head;
    183                 leftTail = head;
    184             } else if (head.val > value) {
    185                 rightTail.next = head;
    186                 rightTail = head;
    187             } else {
    188                 equalTail.next = head;
    189                 equalTail = head;
    190             }
    191             head = head.next;
    192         }
    193         
    194         leftTail.next = null;
    195         rightTail.next = null;
    196         equalTail.next = null;
    197         
    198         if (leftDummy.next == null && rightDummy.next == null) {
    199             ListNode mid = findMedian(equalDummy.next);
    200             leftDummy.next = equalDummy.next;
    201             rightDummy.next = mid.next;
    202             mid.next = null;
    203         } else if (leftDummy.next == null) {
    204             leftTail.next = equalDummy.next;
    205         } else {
    206             rightTail.next = equalDummy.next;
    207         }
    208         
    209         return new Pair(leftDummy.next, rightDummy.next);
    210     }
    211     
    212     private ListNode getTail(ListNode head) {
    213         if (head == null) {
    214            return null;
    215         } 
    216        
    217         while (head.next != null) {
    218             head = head.next;
    219         }
    220         return head;
    221     }
    222 }
  • 相关阅读:
    VueBlog
    java 代理模式
    集合框架
    面试题
    java 多线程
    网络编程
    HTTP
    MAVEN
    Redis高级
    深入浅出--梯度下降法及其实现
  • 原文地址:https://www.cnblogs.com/hygeia/p/5062446.html
Copyright © 2011-2022 走看看