-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSortList.java
161 lines (136 loc) · 4.04 KB
/
SortList.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package linked_list;
/**
* @Author: Wenhang Chen
* @Description:在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
* <p>
* 示例 1:
* <p>
* 输入: 4->2->1->3
* 输出: 1->2->3->4
* 示例 2:
* <p>
* 输入: -1->5->3->4->0
* 输出: -1->0->3->4->5
* @Date: Created in 8:34 12/15/2019
* @Modified by:
*/
public class SortList {
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
}
}
// 递归写法
// 经典写法,但空间复杂度 O(logn),不符合题意
public ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode slow = head;
ListNode fast = head.next;
// 用快慢指针找到中间结点
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// 由中部切断
ListNode tmp = slow.next;
slow.next = null;
// 递归,不断二分
ListNode left = sortList(head);
ListNode right = sortList(tmp);
ListNode h = new ListNode(0);
ListNode res = h;
// merge
while (left != null && right != null) {
if (left.val < right.val) {
h.next = left;
left = left.next;
} else {
h.next = right;
right = right.next;
}
h = h.next;
}
h.next = left == null ? right : left;
return res.next;
}
// 自下而上归并排序,空间复杂度O(1)
public ListNode sortList2(ListNode head) {
if (head == null || head.next == null) return head;
ListNode h = head;
int length = 0, intv = 1;
while (h != null) {
h = h.next;
length += 1;
}
ListNode res = new ListNode(0);
res.next = head;
while (intv < length) {
ListNode pre = res;
h = res.next;
while (h != null) {
ListNode h1 = h;
int i = intv;
while (i != 0 && h != null) {
h = h.next;
i -= 1;
}
if (i != 0) {
break;
}
ListNode h2 = h;
i = intv;
while (i != 0 && h != null) {
h = h.next;
i -= 1;
}
int c1 = intv, c2 = intv - i;
while (c1 != 0 && c2 != 0) {
if (h1.val < h2.val) {
pre.next = h1;
h1 = h1.next;
c1 -= 1;
} else {
pre.next = h2;
h2 = h2.next;
c2 -= 1;
}
pre = pre.next;
}
pre.next = c1 != 0 ? h1 : h2;
while (c1 > 0 || c2 > 0) {
pre = pre.next;
c1 -= 1;
c2 -= 1;
}
pre.next = h;
}
intv *= 2;
}
return res.next;
}
/**
* 归并两个已经排好序的单链表,是我们非常熟悉的操作了,可以递归完成,也可以穿针引线,这里我们递归完成
*
* @param l1 顺序存放的单链表1
* @param l2 顺序存放的单链表2
* @return 合并以后的单链表
*/
// private ListNode mergeOfTwoSortedListNode(ListNode l1, ListNode l2) {
// ListNode h = new ListNode(0);
// ListNode res = h;
// while (l1 != null && l2 != null) {
// if (l1.val < l2.val) {
// h.next = l1;
// l1 = l1.next;
// } else {
// h.next = l2;
// l2 = l2.next;
// }
// h = h.next;
// }
// h.next = l1 != null ? l1 : l2;
// return res.next;
// }
}