LeetCode 11.盛最多水的容器

11.盛最多水的容器

题面:

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, heighti) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例:(建议参考原题面)

输入:1,8,6,2,5,4,8,3,7

输出:49

解释:(8, 7)情况下,容器能够容纳水的最大值为 49。

解析:
  • 对于这道题目,暴力就是两层循环,遍历所有的左右栏杆的情况,求解出其中的最大值。
  • 优化:我们可以进行的优化就是在答案的搜索空间内减少不必要的遍历验证。
  • 双指针的思想:它先令底边(right - left)最大,这样我们接下来的任何遍历操作都会使得底边变小。设当前我们遍历至stepi,此时的面积为min(heightleft, heightright) * (right - left),对于stepi+1而言,我们可以进行的操作就是右移左边的栏杆(left++)与左移右边的栏杆(right--)。此时不论移动哪一边,底边都是变小,不妨设heightleft < heightright,ans = heightleft * (right - left),如果我们移动长的栏杆,会出现下面两种情况: c a s e 1 : h e i g h t − − r i g h t < h e i g h t l e f t → a r e a = h e i g h t − − r i g h t ∗ ( r i g h t − l e f t − 1 ) → a r e a < a n s c a s e 2 : h e i g h t − − r i g h t ≥ h e i g h t l e f t → a r e a = h e i g h t l e f t ∗ ( r i g h t − l e f t − 1 ) → a r e a < a n s case_1:height--right < heightleft \rightarrow area = height--right * (right - left - 1) \rightarrow area < ans\\case_2:height--right ≥ heightleft \rightarrow area = heightleft * (right - left - 1) \rightarrow area < ans case1:height−−right<heightleft→area=height−−right∗(right−left−1)→area<anscase2:height−−right≥heightleft→area=heightleft∗(right−left−1)→area<ans
  • 此后我们会发现,移动长的一条边的话,我们的搜索就是无意义的了,我们在以当前的面积为上界进行搜索,但是如果我们移动较短的一条边,就会有如下三种情况:
    c a s e 1 : h e i g h t + + l e f t > h e i g h t r i g h t → a r e a = h e i g h t r i g h t ∗ ( r i g h t − l e f t − 1 ) → a r e a ? a n s c a s e 2 : h e i g h t + + l e f t = h e i g h t r i g h t → a r e a = h e i g h t r i g h t ∗ ( r i g h t − l e f t − 1 ) → a r e a ? a n s c a s e 3 : h e i g h t + + l e f t < h e i g h t r i g h t → a r e a = h e i g h t + + l e f t ∗ ( r i g h t − l e f t − 1 ) → a r e a ? a n s case_1:height++left > heightright \rightarrow area = heightright * (right - left - 1) \rightarrow area ? ans\\case_2:height++left = heightright \rightarrow area = heightright * (right - left - 1) \rightarrow area ? ans\\case_3:height++left < heightright \rightarrow area = height++left * (right - left - 1) \rightarrow area ? ans case1:height++left>heightright→area=heightright∗(right−left−1)→area?anscase2:height++left=heightright→area=heightright∗(right−left−1)→area?anscase3:height++left<heightright→area=height++left∗(right−left−1)→area?ans
  • 此时我们可以发现,针对于移动较短的一边而言,此时可能存在比当前面积更大的情况,此时的搜索才是有意义的,而对于这道题目而言,就是基于这样实现的双指针,减少了很多无意义的搜索,将O(n ^ 2)的搜索空间使用O(n)的时间复杂度完成最大面积的搜索。
复杂度

时间复杂度
O ( n ) O(n) O(n)
空间复杂度
O ( 1 ) O(1) O(1)

Code
c++ 复制代码
// C++
class Solution {
public:
    int maxArea(vector<int>& height) {
        int left = 0;
        int right = height.size() - 1;
        int ans = min(height[left], height[right]) * (right - left);
        while (left < right)
        {
            if (height[left] <= height[right])
            {
                left++;
            } else
            {
                right--;
            }
            int temp = min(height[left], height[right]) * (right - left);
            ans = max(ans, temp);
        }
        return ans;
    }
};
python 复制代码
# Python
class Solution:
    def maxArea(self, height: List[int]) -> int:
        i, j = 0, len(height) - 1
        ans = min(height[i], height[j]) * (j - i)
        while i < j:
            if height[i] <= height[j]:
                i += 1
            else:
                j -= 1
            temp = min(height[i], height[j]) * (j - i)
            ans = max(temp, ans)
        return ans
rust 复制代码
// Rust
use std::cmp;

impl Solution {
    pub fn max_area(height: Vec<i32>) -> i32 {
        let mut left = 0;
        let mut right = height.len() - 1;
        let mut ans = cmp::min(height[left], height[right]) * (right - left) as i32;
        while left < right
        {
            if height[left] <= height[right]
            {
                left += 1;
            } else {
                right -= 1;
            }
            let temp = cmp::min(height[left], height[right]) * (right - left) as i32;
            ans = cmp::max(ans, temp);
        }
        ans
    }
}
相关推荐
k4m7v2pz21 分钟前
Bevy 0.14.2 玩家精灵不渲染(只有背景在动)排查全记录
macos·rust·bevy
BerryS3N1 小时前
Java 后端转型大模型:Demo 能跑不等于能上线
java·人工智能·python·java后端·spring ai·langchain4j·大模型转型
冻柠檬飞冰走茶1 小时前
PTA基础编程题目集 7-19 支票面额(C语言实现)
c语言·开发语言·数据结构·算法
制造数据与AI践行者老蒋1 小时前
智联工坊实战:从“金鱼记忆”到“记住了”:给制造Agent装上记忆芯片的完整指南
人工智能·python·langchain·制造
某林2121 小时前
ros从底层硬件到 Web 端部署
python·机器人·硬件架构·ros2
你怎么知道我是队长1 小时前
计算机虚拟存储管理与页面置换算法详解
服务器·网络·算法
罗西的思考1 小时前
【Agentic RL / 强化学习 / OPD】OpenClaw-RL 源码阅读笔记 — (14)— Teacher
人工智能·笔记·深度学习·算法·机器学习
塔能物联运维1 小时前
塔能两相液冷:600W/cm²极限能力,为下一代AI芯片预留充足散热余量
人工智能·算法·两相液冷
FBI HackerHarry浩1 小时前
AI大模型开发V2第四阶段机器学习概述
人工智能·python·机器学习
axinawang2 小时前
第22课 石头剪刀布
python