这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战
盛最多水的容器
该题出自力扣的11题——盛最多水的容器(中等题),自己消化实现
审题
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。 在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
- 题目有点绕,简单概括就是,一个数组,找出其中最长的两个点作为X-Y轴的Y坐标,数组下标为X轴坐标;两点之间的距离为长,宽为两Y轴最短(木桶盛水最短木板原理),求面积
- 本质上需要记录的就是,找出数组内最大的两位数,并记录下坐标
- 最初的想法是暴击记录,但是代码会很繁琐
- 双重for循环方法,也不是不可以,但是容易超时,时间复杂度O(n²)
- 这是极其经典的双指针面试题,直接指向首尾,并取最短的往前推
- 双指针代表的是 可以作为容器边界的所有位置的范围。在一开始,双指针指向数组的左右边界,表示 数组中所有的位置都可以作为容器的边界,因为我们还没有进行过任何尝试。在这之后,我们每次将 对应的数字较小的那个指针 往 另一个指针 的方向移动一个位置,就表示我们认为 这个指针不可能再作为容器的边界了。
- 时间复杂度:O(N),双指针总计最多遍历整个数组一次。
- 空间复杂度:O(1),只需要额外的常数级别的空间。
题解
这题的解题思路有点像内卷,评论区企业级理解:走出舒适圈就是,每次都移动自己最差的一边,虽然可能会变得更差,但是总比不动强
public static int maxArea(int[] height) {
//双指针思路,内卷含义——先卷死差的
int l =0,len = height.length,r = len -1;
int max =0;
while (r>l){
int temporary = (r-l) * (Math.min(height[l],height[r]));
if (height[l]>height[r]){
r--;
}else {
l++;
}
max = Math.max(max,temporary);
}
return max;
}