Day5 排序链表 乘最多水的容器 合并K个排序链表
Posted 未来可期-2018
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day5 排序链表 乘最多水的容器 合并K个排序链表相关的知识,希望对你有一定的参考价值。
排序链表
使用分治方法对链表排序,其中如何对链表进行分割成了问题,一开始的想法是先求出链表的总长度,然后再利用双指针求出中点;而有更巧妙的方法,设两个指针,l1和l2,一个走一步,一个走两步,正好一个到达末尾时另外一个到达中点,该法也曾用于判断链表是否有环(追及相遇问题);或者再推广,利用此法可以直接求链表的n分点,即设n个指针,依次每次走
(
i
=
1
,
2
,
⋯
,
n
)
(i=1,2,\\cdots,n)
(i=1,2,⋯,n)步。
class Solution(object):
def sortList(self, head):
if not head:
return None
elif not head.next:
return head
# 准备数据
# cnt=0
# l=head
# while l:
# cnt+=1
# l=l.next
# l=head
# r=head
# i=-1
# while i<(cnt>>1):
# l=l.next
# i+=1
# while l:
# l=l.next
# r=r.next
# left=r
# right=r.next
# left.next=None
# left=head
#对于链表我们可以递归地将当前链表分为两段,然后merge,分两段的方法是使用双指针法,p1指针每次走两步,p2指针每次走一步,直到p1走到末尾,这时p2所在位置就是中间位置,这样就分成了两段。
left=head
right=head
global pre
pre=None
while right and right.next:
pre=left
left=left.next
right=right.next.next
pre.next=None
right=left
left=head
# 切分问题 left表示左有序序列 right表示右有序序列
left=self.sortList(left)
right=self.sortList(right)
if not left:
return right
elif not right:
return left
elif not left and not right:
return None
# 合并两个有序链表
global ans
if left.val<=right.val:
ans=left
left=left.next
else:
ans=right
right=right.next
r=ans
while left and right:
if left.val<=right.val:
r.next=left
r=r.next
left=left.next
else:
r.next=right
r=r.next
right=right.next
if left:
r.next=left
else:
r.next=right
return ans
合并K个升序链表
使用分治法合并k个有序链表,将k个链表合并问题分解为2个有序链表合并
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution(object):
# 分治
def mergeKLists(self, lists):
if not lists or len(lists)==0:
return None
elif len(lists)==1:
return lists[0]
# 分解问题
left=self.mergeKLists(lists[:len(lists)//2])
right=self.mergeKLists(lists[len(lists)//2:])
if not left:
return right
elif not right:
return left
# 合并两个有序链表
global ans
if left.val<=right.val:
ans=left
left=left.next
else:
ans=right
right=right.next
r=ans
while left and right:
if left.val<=right.val:
r.next=left
r=r.next
left=left.next
else:
r.next=right
r=r.next
right=right.next
if left:
r.next=left
else:
r.next=right
return ans
乘最多水的容器
双指针法,每次移动较小的那端,因为固定较小的那端,移动大的那端,高取决于较小的那端,但是间距必然减少,面积必然减少;移动较小的那端,高可能会更大,面积可能更大
class Solution(object):
def maxArea(self, height):
i=0
j=len(height)-1
ans=0
while i<j:
ans=max(ans,min(height[i],height[j])*(j-i))
# 每次移动较小的那端,因为固定较小的那端,移动大的那端,面积必然减少
if height[i]<=height[j]:
i+=1
else:
j-=1
return ans
以上是关于Day5 排序链表 乘最多水的容器 合并K个排序链表的主要内容,如果未能解决你的问题,请参考以下文章