标签:
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 }
标签:
原文地址:http://www.cnblogs.com/hygeia/p/5062446.html