今日头条-最大区间问题Java求解
问题:
给定一个数组序列, 需要求选出一个区间, 使得该区间是所有区间中经过如下计算的值最大的一个:
区间中的最小数 * 区间所有数的和最后程序输出经过计算后的最大值即可,不需要输出具体的区间。
如给定序列 [6 2 1]则根据上述公式, 可得到所有可以选定各个区间的计算值:
[6] = 6 * 6 = 36;
[2] = 2 * 2 = 4;
[1] = 1 * 1 = 1;
[6,2] = 2 * 8 = 16;
[2,1] = 1 * 3 = 3;
[6, 2, 1] = 1 * 9 = 9;
从上述计算可见选定区间 [6] ,计算值为 36, 则程序输出为 36。
区间内的所有数字都在[0, 100]的范围内;
输入描述:
第一行输入数组序列长度n,第二行输入数组序列。
对于 50%的数据, 1 <= n <= 10000;
对于 100%的数据, 1 <= n <= 500000;
输出描述:
输出数组经过计算后的最大值。
输入例子1:
3
6 2 1
输出例子1:
36
思路:
- 从分治角度思考,先找出问题的分水岭在输入值为0和输入值结束时,即通过出现0(因为出现0的情况必定使输出结果为0,所有可以跳过)或输入结束两种判断,将输入数组切割成多份
- 接下来问题就变成从每个切割数组中读取最小值*切割数组和的问题了
- 另外要注意数组有顺序问题,笔者一开始没注意看,以为是可以跳过数组数字的问题,导致写的时候出现一些问题
开始上代码:
import java.util.Scanner;
public class MaxSum {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int count = Integer.parseInt(sc.nextLine());
String[] arr = sc.nextLine().split("\\s+");
int left = 0;//左边界
int right = 0;//右边界
long max = Long.parseLong(arr[0])*Long.parseLong(arr[0]);//最大值
while (right < count){
long node = Long.parseLong(arr[right]);
if (node == 0 || right == count - 1){
for (int i = left; i <= right; i++){
long tmp = Long.parseLong(arr[i])*Long.parseLong(arr[i]);
long min = Long.parseLong(arr[i]);
if (tmp > max)
max = tmp;
if (i != right){
long sum = Long.parseLong(arr[i]);
for (int j = i+1; j <= right; j++){
if (min > Long.parseLong(arr[j]))
min = Long.parseLong(arr[j]);
sum += Long.parseLong(arr[j]);
tmp = sum * min;
if (tmp > max)
max = tmp;
}
}
}
left = right + 1;
}
right++;
}
System.out.println(max);
}
}
在牛客网跑了一下,是可以通过所有测试用例的,先记录一些,日后有时间再进行优化