code148: Sort List
Add to List
Share
Sort a linked list in O(n log n) time using constant space complexity.
Example 1:
Input: 4->2->1->3
Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0
Output: -1->0->3->4->5
解答:
看到logn基本确定是有二分的想法在里面
我的想法:
类似快排,每个链的head作为pivot,然后遍历,小的新建链放在左边,大的新建链放在右边。得到三个(left, pivot, right),然后进行整合为新链。内部进行递归细分整合。
代码:
class Solution:###TLE ###quick sort
def sortList(self, head: ListNode) -> ListNode:
return self.sort_node(head)
def sort_node(self, node):
#print('#')
if not node:
return None
else:
#print(node.val)
new_node1, new_node2 = ListNode(0), ListNode(0)
new_nodel, new_noder = ListNode(0), ListNode(0)
new_nodel.next = new_node1
new_noder.next = new_node2
# new_node1.next = node
pivot = node
# new_node1 = new_node1.next
while node.next:
#print('???')
if node.next.val < pivot.val:
new_node1.next = node.next
new_node1 = new_node1.next
else:
new_node2.next = node.next
new_node2 = new_node2.next
node = node.next
#if new_node1.next:
new_node1.next = None
new_node2.next = None
new_nodel.next.next = self.sort_node(new_nodel.next.next)
new_noder.next.next = self.sort_node(new_noder.next.next)
return self.merge(new_nodel.next.next, pivot, new_noder.next.next)
def merge(self, node1, pivot, node2):
#print('?')
new_node = ListNode(0)
if node1:
new_node.next = node1
#print(node1.val)
while node1:
#print('??????')
if node1.next:
print(node1.val)
node1 = node1.next
else:
break
#print(node1.val)
node1.next = pivot
else:
new_node.next = pivot
pivot.next = node2
return new_node.next
这段代码最后的例子超时。分析是因为在合并的时候做的左半边再次遍历导致时间复杂度提升。
先看看后面解答里面别人提供的归并思想。其实最开始也是想到的归并,但是归并需要找到中点,不太好操作就否决了。现在的操作:
1 设置 fast slow, 前者进行.next.next遍历,后者进行.next遍历。终止位置的slow就是中点。
2 然后分离左右部分,将左边最后设置为None,右边头设置为slow
3 进行递归
4 合并,类似归并的做法。
代码:
class Solution:#merge sort
def sortList(self, head: ListNode) -> ListNode:
#print(head.val)
if not head or not head.next:
return head
else:
slow = head
fast = head.next
while slow and fast:
if fast.next:
if fast.next.next:
fast = fast.next.next
else:
break
else:
break
slow = slow.next
#print(slow.val)
r = slow.next
slow.next = None
l = head
l = self.sortList(l)
r = self.sortList(r)
return self.merge(l,r)
def merge(self, h1,h2):
pre = tail = ListNode(0)
while h1 or h2:
if not h2:
pre.next = h1
break
elif not h1:
pre.next = h2
break
elif h1.val>h2.val:
pre.next = h2
pre = pre.next
h2 = h2.next
else:
pre.next = h1
pre = pre.next
h1 = h1.next
return tail.next
tips:
1 寻找链表中点的有效方法之一就是进行fast,slow的操作
2 链表中间切断时,结尾需要连上None
来源:CSDN
作者:Magnum_yuanz
链接:https://blog.csdn.net/weixin_39238424/article/details/104301884