• Leetcode#11 Container With Most Water


    原题地址

    最朴素的想法就是,枚举容器的左边界和右边界,总能找到解,不过时间复杂度是O(n^2)的。

    改进I:从左向右枚举左边界,在此基础上从右向左枚举右边界,一旦右边界高度>=左边界高度就可以停止枚举了,因为继续枚举下去找到的矩形肯定面积更小。

    比如下图,左边界在位置0,高度为height[0]=3,那么,右边界枚举到位置5就可以停止了(height[5]=4 >= 3=height[0])。

         |
    | |
    | | |
    | | | | | |
    | | | | | | |
    +-+-+-+-+-+-+
    0 1 2 3 4 5 6
    ^ ^
    左边界 右边界

    改进II:

    在改进I中,要从左到右枚举左边界,但是左边界是否要一直枚举到最右边呢?当然不是。

    看下图,假设现在枚举到了这个位置:左边界高度是2,右边界高度也是2。

         |
    | |
    | | |
    | | | | | |
    | | | | | | |
    +-+-+-+-+-+-+
    0 1 2 3 4 5 6
    ^ ^
    左边界 右边界

    那么,左边界在以后向右移动的时候,凡是高度小于等于2的位置都不用考虑了(图中位置3、4),因为肯定不会超过当前这个矩形的面积。

    所以,每次枚举的时候根据右边界高度更新这个阈值,以后遇到阈值低于这个的左边界就不用考虑了。

    改进III

    在改进II中,先确定左边界,然后去枚举右边界,同时右边界又对左边界的选择有一定影响。仔细想想,左右边界本身没有区别,所以可以从两头分别开始枚举,更新阈值。如果左边界比右边界矮,左边界决定了最终矩形的高度,以后不会再有比这个矩形矮并且面积更大的矩形出现了,所以让左边界向右移动一个单位。同理如果右边界比左边界矮,右边界向左移动一个单位。

    这就是最终的算法了。

    代码:

     1 int maxArea(vector<int> &height) {
     2         int l = 0;
     3         int r = height.size() - 1;
     4         int res = 0;
     5         
     6         while (l <= r) {
     7             res = max(res, (r - l) * min(height[l], height[r]));
     8             if (height[l] < height[r])
     9                 l++;
    10             else
    11                 r--;
    12         }
    13         
    14         return res;
    15 }
  • 相关阅读:
    干货—MySQL常见的面试题+索引原理分析!
    如何设计一个百万级的消息推送系统
    【金三银四跳槽季】Java工程师如何在1个月内做好面试准备?
    Nginx实现请求的负载均衡 + keepalived实现Nginx的高可用
    java函数式编程之Supplier
    SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置
    Redis创建集群报错
    阿里云服务器Tomcat无法从外部访问
    SSM框架学习之高并发秒杀业务--笔记5-- 并发优化
    在windows上部署使用Redis
  • 原文地址:https://www.cnblogs.com/boring09/p/4255410.html
Copyright © 2020-2023  润新知