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

本题是Bloomberg的面试题。

问题描述:

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

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

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

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

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

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

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

直到 指针 i 遍历完成。 

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

实现代码:

class Solution {
public:
    int maxArea(vector& 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 ;

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

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

实现代码:

/// Two Pointers
/// Time Complexity: O(n)
/// Space Complexity: O(1)
class Solution {
public:
    int maxArea(vector& 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& 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 不变;

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

 ② i = 1, j = 8;

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

然后 j--;

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

 

 ③ i = 1, j = 7;

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

然后 j  -- ;

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

 ④ i = 1, j =6;

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

然后 j -- ;

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

 ⑤ i = 2, j =5;

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

然后 j -- ;

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

 

⑥ i = 2, j =4;

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

然后 j -- ;

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

 

⑦ i = 2, j =3;

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

然后 j -- ;

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

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

 

参考资料:

1)刘宇波的github

2)www.leetcode.com

你可能感兴趣的:(LeetCode)