Skip to content

Commit 83f334c

Browse files
author
weiy
committed
sort list medium
1 parent 83dc486 commit 83f334c

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

Sorted/SortList.py

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
"""
2+
Sort a linked list in O(n log n) time using constant space complexity.
3+
4+
Example 1:
5+
6+
Input: 4->2->1->3
7+
Output: 1->2->3->4
8+
Example 2:
9+
10+
Input: -1->5->3->4->0
11+
Output: -1->0->3->4->5
12+
13+
O (n log n) 用归并排序比较好。
14+
15+
难点在于常量空间复杂度...
16+
17+
暂不解决这个问题,再回顾下归并排序。
18+
19+
归并排序的核心思路是分治,将大问题分成小问题,再将已经解决的小问题不断合并成一个解决方案。
20+
21+
所以归并排序的话先分割,进行对半分割即可。
22+
23+
_left = list[:middle]
24+
_right = list[middle:]
25+
26+
分割成 _left 和 _right 后,要做的是归并。
27+
28+
merge_sort(_left, _right)
29+
30+
这里就归并用到底不做剪枝优化了。
31+
32+
merge_sort
33+
的关键词是:
34+
1. _left 和 _right 分别挑剩余的最小的合并到一个集合里。
35+
2. 若 _left 耗尽,直接合并 _right。
36+
3. _right 同理。
37+
38+
def merge_sort(_left, _right):
39+
_l_index = 0
40+
_r_index = 0
41+
42+
_l_length = len(l)
43+
_r_length = len(r)
44+
45+
while _l_i < _l_l and _r_i < _r_l:
46+
if l[_l_i] < r[_r_l]:
47+
l[_l_i]
48+
_l_i += 1
49+
else:
50+
r
51+
52+
if _l_i == _l_l:
53+
extend _r
54+
55+
if _r_i == _r_l:
56+
extend _l
57+
58+
return result
59+
60+
61+
这是最原始的 split ,后面要扩展一下才能用。
62+
def split(list):
63+
64+
_left = list[:middle]
65+
_right = list[middle:]
66+
67+
return merge_sort(_left, _right)
68+
69+
在初次分割之后,_left 和 _right 确实分成了两份,但都是未经过排序的,直接用merge_sort的话是不行的(这里展开思考的话,会想到另一种排序——堆排序)。
70+
71+
我们需要对_left和_right分别再次进行 分割-合并。
72+
73+
def split(list):
74+
75+
_left = split(list[:middle])
76+
_right = split(list[middle:])
77+
78+
return merge_sort(_left, _right)
79+
80+
写到这里还有点问题,这样会无限分割下去,在加一个判断用于结束递归。
81+
82+
def split(list):
83+
if len(list) <= 1:
84+
return list
85+
86+
_left = split(list[:middle])
87+
_right = split(list[middle:])
88+
89+
return merge_sort(_left, _right)
90+
91+
元素<=1个时就可以返回了。
92+
93+
[1, 2, 4, 5]
94+
left ↓ right
95+
[1, 2] [4, 5]
96+
left↓right left↓right
97+
[1] [2] [4] [5]
98+
到这里
99+
不在分割 [1] [2] 分别返回,然后执行了
100+
merge_sort([1], [2])
101+
merge_sort([4], [5])
102+
103+
然后再返回...
104+
105+
106+
beat:
107+
84%
108+
测试地址:
109+
https://leetcode.com/problems/sort-list/description/
110+
111+
"""
112+
# Definition for singly-linked list.
113+
# class ListNode(object):
114+
# def __init__(self, x):
115+
# self.val = x
116+
# self.next = None
117+
118+
class Solution(object):
119+
def sortList(self, head):
120+
"""
121+
:type head: ListNode
122+
:rtype: ListNode
123+
"""
124+
lists = []
125+
126+
while head:
127+
lists.append(head.val)
128+
head = head.next
129+
130+
131+
def merge_sort(l, r):
132+
133+
_l = 0
134+
_r = 0
135+
136+
_l_length = len(l)
137+
_r_length = len(r)
138+
139+
result = []
140+
141+
while _l < _l_length and _r < _r_length:
142+
if l[_l] < r[_r]:
143+
result.append(l[_l])
144+
_l += 1
145+
else:
146+
result.append(r[_r])
147+
_r += 1
148+
149+
if _l == _l_length:
150+
while _r < _r_length:
151+
result.append(r[_r])
152+
_r += 1
153+
else:
154+
while _l < _l_length:
155+
result.append(l[_l])
156+
_l += 1
157+
158+
return result
159+
160+
def split(l):
161+
if len(l) <= 1:
162+
return l
163+
164+
_l = split(l[:len(l)//2])
165+
_r = split(l[len(l)//2:])
166+
167+
return merge_sort(_l, _r)
168+
169+
lists = split(lists)
170+
171+
if not lists:
172+
return None
173+
174+
head = ListNode(lists[0])
175+
176+
_head = head
177+
178+
for i in lists[1:]:
179+
head.next = ListNode(i)
180+
head = head.next
181+
182+
return _head
183+

0 commit comments

Comments
 (0)