用简单通俗易懂的话来记录自己对数组算法的理解
1.原题
1.题目
给定n个非负整数a1,a2,…,an,其中每个数字表示坐标(i, ai)处的一个点。以(i,ai)和(i,0)(i=1,2,3…n)为端点画出n条直线。你可以从中选择两条线与x轴一起构成一个容器,最大的容器能装多少水?
注意:你不能倾斜容器
输入 [1,8,6,2,5,4,8,3,7]
输出: 49
2.分析
1.分析
要求面积最大,只要做个遍历,把所有组合求出来即可,但是,这样的话,就要使用两个for循环,时间负责度是O(n2),空间复杂度O(1),这个肯定不是最优解,是否有能使用更好的时间从而来实现呢?
一直考虑使用O(n)时间复杂度,这里就介绍双针法。双针法就是从两端进行同时进行遍历,满足一定条件,停止遍历(比如头部i>=尾部j)。而要不断的i++或者j–,则使用f(x)与f(j)的大小比较,这种方式正好满足今天的题目。今天题目是求最大面积,我们知道,随着长的减小,我们期望宽更大,才能达到最大值的比较,因此,刚好满足这里的条件。
3.思路
(1)声明临时变量,标记为最大长方形面积maxArea;
(2)首尾开始遍历,当i<j时,继续,当i>=j时,停止。
当i<j时,比较数组arr[i]与arr[j]
arr[i] > arr[j]时,用arr[j]作为宽,j–,寻找更大的高
arr[i]<= arr[j]时,用arr[i]作为宽,i++,寻找更大的高
(3)每次进行maxArea进行比较赋值。
4.代码
private int getMaxArea(int[] arr){
int maxArea = 0;
int length = arr.length;
if (length < 2) {
return 0;
}
int i = 0;
int j = length - 1;
while (i < j) {
if(arr[i] < arr[j]){
maxArea = Math.max(maxArea,(j-i)*arr[i]);
i++;
}else{
maxArea = Math.max(maxArea,(j-i)*arr[j]);
j--;
}
}
return maxArea;
}
结果:
arr1.areaSize:2
arr2.areaSize:49