//日期:19..4.18
//作者:***
//功能:我的面试编程题目二十五
//===============================================
//问题描述:
//给定int数组,每一个元素代表高度,而数组下标差代表宽度,
//当高度不一致的时候,我们取较小值,然后乘宽度,作为面积,
//求这个数组中选取两元素,所能构成的最大面积
//例如 1 2 3 4 5 6 7 8
//很显然,我们选取 7 8可以构成面积 (8-7)*7=7
//但是我们选取4 8可以构成面积(8-4)*4=16
//================================================
//思路方法:假如 数组表示为:1 8 5 7 6 5 2 6
//很明显,我们用双重for循环可以暴力解决这个问题,但是时间复杂度很高
//那么现在就考虑有没有什么逻辑,可以减少这种暴力解决所带来的没有必要的比较
//那么我们仔细想这个问题,因为for循环之所以要两重,其实就是因为要找到两个高度
//那么我们想要较少for或者减少逻辑比较,能不能找个其他的变量来实现呢
//回归问题,求面积,面积公式 高 * 宽,那既然选择高有两层for,我们考虑选择宽
//我们假设:一开始我们选择数组的两个边界,首部和尾部,此时宽度最大
//高为a[0]和a[7]中较小的一个,此时宽度下的选择只有这一种
//那么在考虑宽度为len-1;此时的选择就有两种
//一种是a[0]和a[6].另外一种是a[1]和a[7],那么从a[0]_a[7]向其转换的时候
//有没有一种逻辑上的联系呢?
//其实不难发现:
//如果 a[0] < a[7],左边高度小于右边高度,
//那么减少宽度的时候,如果还是以左边a[0]为一个高度,那么无论右边怎么选择,一定小于a[0]_a[7]
//很好理解,你的宽度减少了,无论是宽度减几,想要是面积增大,只能增大高度,
//但是a[0]已经确认,那么无论你右边多大,只能取小的a[0],如果你右边更小,那就更不可能了
//而a[0]又是小于a[7]的,显然这所有的操作都没有意义,因为结果早就确定了一定小于a[0]_a[7]
//所以,当a[0]小于a[7]的时候,只能通过改变a[0],才有可能在后续找到面积更大的
//所以。让a[0]右移,否则同样的道理,a[7]左移
//于是时间复杂度就减少到了o(n)
//其实就相当于 每一个宽度下,我们只比较一次,因为宽度从大到小遍历,
//每一个宽度下,我们只需要比较一次即可,(很久了上一次比较所带来的隐藏信息)
package com.**********;
import java.util.*;
public class Practice {
//主函数,作为程序代码测试的入口
public static void main(String args[])
{
Practice p = new Practice();
p.run();
}
//封装函数,与客户端交互的代码
public void run()
{
System.out.println("请输入一组int数据,构成一个处理数组(空格隔开):");
Scanner scan = new Scanner(System.in);
String[] strc = scan.nextLine().split(" ");
scan.close();
int[] weight_array = new int[strc.length];
for(int i=0; i<strc.length; i++)
{
weight_array[i] = Integer.parseInt(strc[i]);
}
int result = this.getResult(weight_array);
System.out.println("程序处理结果显示如下:"+result);
}
//疯转函数,代码的实际测试
public int getResult(int[] weight_array)
{
int result = 0;
int left = 0; //选取两个高度,左边一个的下标
int right = weight_array.length - 1; //选取两个高度,右边一个的下标
while(left < right) //循环找两个下标,确定最大值
{
result = Math.max(result,
Math.min(weight_array[left], weight_array[right])*(right-left));
if(weight_array[left] < weight_array[right])
{
left++;
}else
right--;
}
return result;
}
}
程序测试代码显示;