一道算法题
题目:
给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点(i,ai) 。在坐标内画 n 条垂直线,垂直线 i的两个端点分别为(i,ai) 和 (i, 0) 。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
解法一:暴力解法
- 直接通过双循环将全部可能组成的面积算出来
//暴力解法
private static int method01(int[] num) {
//假设最大面积为0
int maxArea=0;
//判断是数组是否为空
if(num==null||num.length==0){
return maxArea;//不能使用异常
//throw new NullPointerException("it Cannot Be Empty");
}
//遍历数组
for (int i = 0; i < num.length-1; i++) {
//双循环实现i~i+1 i~i+2 i~i+3……之间的面积
for (int j = i+1; j < num.length; j++) {
//判断i与i+n之间的最小的作为高,j-i作为宽
maxArea=Math.max(maxArea,(j-i)*Math.min(num[i],num[j]));
}
}
return maxArea;
}
//=========================================================
//测试
public static void main(String[] args) {
//int[] num={1,2,5,9,3,9};
//int[] num={1,8,6,2,5,4,8,3,7};
int[] num={4,3,2,1,4};
//int[] num=null;
int area=method01(num);
System.out.println("area:"+area);
}
测试结果一:
测试结果二:
解法二:双指针解法
- 两个指针一个数组头一个数组尾部,当index01==index02时,退出
//双指针解法
private static int method02(int[] num) {
//判断是数组是否为空
if(num==null||num.length==0){
throw new NullPointerException("it Cannot Be Empty");
}
int maxArea=0;
//两个指针分别指向数组两端,当两指针相等时则结束
for(int left=0,rigth=num.length-1;left<rigth;){
//获取每次双指针移动后最小的高度
int min=num[left]<num[rigth]?num[left++]:num[rigth--];
//获取面积,每次指针移动一次进行判断是否是最大面积
//此处rigth+1,因为上方rigth--,导致右边指针有-1的偏移量
maxArea=Math.max(maxArea,(rigth+1-left)*min);
}
return maxArea;
}
测试结果一:
测试结果二: