leetcode 11 盛水最多的容器

11. 盛最多水的容器 - 力扣(LeetCode) (leetcode-cn.com)

借助本题来学习下双指针的用法和贪心算法

贪心算法:

        在对问题求解的时候,总是做出当前看来是最好的选择,也就是说,仅仅考虑局部最优解,来组成最终的最优解

        使用的前提条件是确定当前题目的每一步的局部最优解能换来最终的最优解,即要知道什么时候可以贪,什么时候不能贪

        无法确定的时候往往需要进行数学证明来验证最后得到的是最优解

双指针:

        顾名思义,就是利用两个指针去遍历数组,一般来说,遍历数组采用的是单指针(index)去遍历,两个指针一般是在有序数组中使用,一个放首,一个放尾,同时向中间遍历,直到两个指针相交,完成遍历,时间复杂度也是O(n)。

        双指针又分为快慢指针和对撞指针 本题用到的是对撞指针,当遇到有序数组时,应该优先想到双指针来解决问题,因两个指针的同时遍历会减少空间复杂度和时间复杂度。

思路:

        1.左指针从第一个开始向右移动,右指针从最后一个开始向左移动

        2.设置初始答案为右指针左指针所指的值的最小值乘以左右指针的距离(盛水的area)

        3. 移动左右指针当中对应数值较小的那一个来寻求局部最优解(证明附后)

        4.比较当前解和之前的解的大小,储存较大的那个作为新解

        5.返回第三步,直到左右指针相撞

        6.返回解

伪证明:

        假设左右指针分别对应的值是x, y且x<=y那么且距离为s,此时面积area为s*min(x, y)。当保证最小值不变的情况下移动右指针的时候,由于x不变,且s变小,所以area最大不会超过原来的area,所以要移动较小的那个值的指针

代码部分:

        

class Solution:
    def maxArea(self, height: List[int]) -> int:
        # 经典双指针
        lk, rk = 0, len(height) - 1
        ans = (rk - lk) * min(height[rk], height[lk])
        while lk != rk:
            if height[lk] >= height[rk]:
                rk -= 1
                ans = max(ans, (rk - lk) * min(height[rk], height[lk]))
            else:
                lk += 1
                ans = max(ans,  (rk - lk) * min(height[rk], height[lk]))
        return ans

感觉还有优化空间,以后有机会改

坚持 共勉

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值