盛最多水的容器

略带减少负担的暴力法

def maxArea(height: list)->int:
    left = (1, height[0])
    right = (2, height[1])
    size = calSize(left, right)
    saveList = []
    if height[0] > height[1]:
        saveList.append(left)
    else:
        saveList.append(right)
    x = 2
    for y in height[2:]:
        x += 1
        now = (x, y)
        if y >= max(left[1], right[1]):
            saveList.append(now)  # 保存高于现在使用高的点
        leftSize = calSize(left, now)
        rightSize = calSize(right, now)
        if leftSize > size or rightSize > size:
            if leftSize > rightSize:
                size = leftSize
                right = now
            else:
                size = rightSize
                left = right
                right = now
        for highSave in saveList[:-1]:
            if calSize(highSave, now) > size:
                left = highSave
                right = now
                size = calSize(left, right)
    print(size)
    print(left)
    print(right)
    print(calSize(left, right))
    print(saveList)
    return size


def calSize(left, right):
    bottom = (right[0] - left[0])
    height = min(left[1], right[1])
    # size = height * bottom
    return height * bottom  # size

双指针法

def maxArea(height: list)->int:
    indexLeft=1
    indexRight=len(height)
    left = (indexLeft, height[indexLeft-1])
    right = (indexRight, height[indexRight-1])
    sizeMax=0
    while indexRight>indexLeft:
        size = calSize(left, right)
        if size>sizeMax:
            sizeMax=size
        if left[1]<right[1]:
            indexLeft+=1
            left = (indexLeft, height[indexLeft-1])
        else :
            indexRight-=1
            right = (indexRight, height[indexRight-1])
    return sizeMax

def calSize(left, right):
    bottom = (right[0] - left[0])
    height = min(left[1], right[1])
    # size = height * bottom
    return height * bottom  # size

暴力法的时间复杂度为o(n2)
空间复杂度为o(1)以上
本人写的暴力法只计算了目前循环到的点与原来的左右俩边界的面积以及保存的比原来俩边界高的点的值
所以如果最好情况,也是有可能只用计算2n次,最差状态是每个点都比前面的高一点,此时我的复杂度甚至会比普通暴力法更高(有重复计算)

所以出现了双指针法:
时间复杂度为o(n)一次扫描
空间复杂度为o(1)
双指针法适用的原因:(双指针原理)
要面积更大,唯有底或高更长,从头尾两边开始,保证了从底最长到底最短,
然后每次将高度更短的往里移动指针,保证了最高高度
因为如果在木桶短板的高度的状态下乘以可能的最大长度也比之前计算的size小,则不可能在底变小情况下后续比之前的size大,所以可以往里移动较小的高度的指针,指望出现高度更高的情况时有可能乘以较小的底大于之前保存的size

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值