题目:
给定n个非负整数a1,a2,…,an,其中每个数字表示坐标(i, ai)处的一个点。以(i,ai)和(i,0)(i=1,2,3...n)为端点画出n条直线。你可以从中选择两条线与x轴一起构成一个容器,最大的容器能装多少水?
注意:你不能倾斜容器
思路:
思路1:暴力求解法,适合数据量较小的情况下。
利用两层循环,对所有可能的组合进行求解。
容积= 长 X 宽 也就是 容积 = 两点纵坐标的较小值 X 两点横坐标的差值
代码:
package com.company;
public class TestNo15 {
public static void main(String[] args) {
TestNo15 t = new TestNo15();
int[] a = {1,8,6,2,5,4,8,3,7};
System.out.println(t.maxArea(a));
}
public int maxArea(int[] height) {
int max = 0;
int tempArea = 0;
int len = height.length;
for(int i = 0;i<len-2;i++){//利用两层循环进行暴力求解出每一个可能的组合
for(int j = i;j<=len-1;j++){
tempArea = (height[i]>height[j] ? height[j] : height[i])*(j-i); //容积 = 两点纵坐标的较小值 * 两点横坐标的差值
if(tempArea > max){
max = tempArea;
System.out.println(i + "," + j);
}
}
}
return max;
}
}
思路2:双指针法,也可以叫做贪心算法。适合数据量较大的情况。
最大的容积的横坐标肯定位于 (start,end)之间。 start 从坐标的起点开始。 end 从坐标的末点开始。start从左向右逐渐遍历,end是从右向左逐渐遍历。知道start = end时候,遍历结束。
max用于存储较大的容积。每次将两点高度较小的点,向内移动。(start++,或者 end--);
package com.company;
public class TestNo15_1 {
public static void main(String[] args) {
TestNo15_1 t = new TestNo15_1();
int[] a = {1,8,6,2,5,4,8,3,7};
System.out.println(t.maxArea(a));
}
public int maxArea(int[] height) {
int max =0;//所能存储的最大容积
int start = 0;//起始点
int end = height.length-1;//末位点
int tempArea = 0;//存储两点所构成的最大容积
while (start < end ){
tempArea = (height[start] > height[end] ? height[end] : height[start]) * (end-start);//两点所构成的最大容积
if(tempArea > max){
max = tempArea; //max存储遍历两点所构成的最大容积
}
if(height[start] > height[end]){ //每次将两点高度更小的那个点向内侧移动
--end;
}
else{
++start;
}
}
return max;
}
}
代码: