Day5 排序链表 乘最多水的容器 合并K个排序链表

排序链表
使用分治方法对链表排序,其中如何对链表进行分割成了问题,一开始的想法是先求出链表的总长度,然后再利用双指针求出中点;而有更巧妙的方法,设两个指针,l1和l2,一个走一步,一个走两步,正好一个到达末尾时另外一个到达中点,该法也曾用于判断链表是否有环(追及相遇问题);或者再推广,利用此法可以直接求链表的n分点,即设n个指针,依次每次走 ( i = 1 , 2 , ⋯   , n ) (i=1,2,\cdots,n) (i=12,,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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值