Problem: 11. 盛最多水的容器
思路
刚看到这道题,很容易想到的是暴力解法, 双层for循环 遍历所有情况,求出最大值. 但是我提交之后超时了… 后来翻阅评论,看到了双指针解法.
解题方法
此解题方法来自力扣评论区.
对O(n)的算法写一下自己的理解,一开始两个指针一个指向开头一个指向结尾,此时容器的底是最大的,接下来随着指针向内移动,会造成容器的底变小,在这种情况下想要让容器盛水变多,就只有在容器的高上下功夫。 那我们该如何决策哪个指针移动呢?我们能够发现不管是左指针向右移动一位,还是右指针向左移动一位,容器的底都是一样的,都比原来减少了 1。这种情况下我们想要让指针移动后的容器面积增大,就要使移动后的容器的高尽量大,所以我们选择指针所指的高较小的那个指针进行移动,这样我们就保留了容器较高的那条边,放弃了较小的那条边,以获得有更高的边的机会。
疑问
对于移动短边,还是有些不解. 感觉会遗漏一些情况. 等理解了补充. 刚刚看了下力扣的题解. 这个问题最大的难点在于为社么双指针不会漏掉可能性. 看了之后理解了一些. 因为水面是在缩小的, 高度取决于短板. 每次-1之后, 必须取长板,水位才有一点可能会上升. 若取短板, 高度不变, 但宽度会-1,面积变小,失去意义. 大家可以参考这个.
题解
复杂度
- 时间复杂度:
添加时间复杂度, 示例: O ( n ) O(n) O(n)
- 空间复杂度:
添加空间复杂度, 示例: O ( n ) O(n) O(n)
Code
class Solution {
public int maxArea(int[] nums) {
int startIndex = 0;
int endIndex = nums.length - 1;
int maxArea = 0;
while (endIndex > startIndex) {
int startNum = nums[startIndex];
int endNum = nums[endIndex];
int area = (endIndex - startIndex) * Math.min(startNum, endNum);
maxArea = Math.max(maxArea, area);
if (startNum > endNum) {
endIndex--;
} else {
startIndex++;
}
}
return maxArea;
}
}