【LeetCode】11. Container With Most Water(盛最多水的容器)-C++实现的三种方法

本题是Bloomberg的面试题。

问题描述:

 一、第一种方法-暴力解法

  当我们在面试时想不到解题的方法时,不妨使用暴力解法,双重遍历数组。

当 i = 0 时,使用指针 j 遍历数组,找到第一轮的最大值 area:

当i = 2 ,使用指针 j 遍历数组,找到第二轮的最大值 area:

直到 指针 i 遍历完成。 

实现代码:

class Solution {
public:
    int maxArea(vector<int>& height) {

        assert(height.size() >= 2);

        int area = 0;
        for(int i = 0 ; i < height.size() ; i ++)
            for(int j = i + 1; j < height.size() ; j ++)
                area = max(area , min(height[i], height[j]) * (j - i));
        return area;
    }
};

时间复杂度:O(n^2)

空间复杂度:O(1)

 

第二种方法:对撞指针法

分别在头、尾元素定义两个指针 l , r ;

如图所示,遍历数组,直到两个指针相遇,停止循环 

实现代码:

/// Two Pointers
/// Time Complexity: O(n)
/// Space Complexity: O(1)
class Solution {
public:
    int maxArea(vector<int>& height) {

        assert(height.size() >= 2);

        int l = 0, r = height.size() - 1;
        int area = 0;
        while(l < r){
            area = max(area , min(height[l], height[r]) * (r - l));
            if(height[l] < height[r])
                l ++;
            else
                r --;
        }
        return area;
    }
};

第三种方法:对撞指针法的优化

首先,使用第一个和最后一行来评估最宽的容器。所有其他可能的容器都不那么宽,所以要有更多的水,它们需要更高。因此,在评估了最宽的容器之后,在两端都跳过不支持更高高度的线。然后评估我们到达的新容器。重复,直到不再有可能的容器。

 实现代码:

int maxArea(vector<int>& height) {
    int water = 0;
    int i = 0, j = height.size() - 1;
    while (i < j) {
        int h = min(height[i], height[j]);
        water = max(water, (j - i) * h);
        while (height[i] <= h && i < j) i++;
        while (height[j] <= h && i < j) j--;
    }
    return water;
}

分析:

①  i = 0, j = 9

 water = 1 * (9 - 0) = 9; 

i ++;   j 不变;

 ② i = 1, j = 8;

water = max(49, 7 *  7) = 49;

然后 j--;

 

 ③ i = 1, j = 7;

water = max(49, 3 *  6) = 49;

然后 j  -- ;

 ④ i = 1, j =6;

water = max(49, 5 *  8) = 49;

然后 j -- ;

 ⑤ i = 2, j =5;

water = max(49, 3 * 4) = 49;

然后 j -- ;

 

⑥ i = 2, j =4;

water = max(49, 2 * 5) = 49;

然后 j -- ;

 

⑦ i = 2, j =3;

water = max(49, 2 * 1) = 49;

然后 j -- ;

两个指针相遇,完成整个遍历过程。

 

参考资料:

1)刘宇波的github

2)www.leetcode.com

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值