时间限制:1000 ms | 内存限制:65535 KB
难度:
4
-
描述
-
给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是相连的。数组中一个或多个连续元素可以组成一个子数组,其中存在这样的子数组arr[i],…arr[n-1],arr[0],…,arr[j],现在请你这个ACM_Lover用一个最高效的方法帮忙找出所有连续子数组和的最大值(如果数组中的元素全部为负数,则最大和为0,即一个也没有选)。
-
输入
- 输入包含多个测试用例,每个测试用例共有两行,第一行是一个整数n(1=<n<=100000),表示数组的长度,第二行依次输入n个整数(整数绝对值不大于1000)。 输出
- 对于每个测试用例,请输出子数组和的最大值。 样例输入
-
6 1 -2 3 5 -1 2 5 6 -1 5 4 -7
样例输出
-
10 14
这题前面没有把握思路, 想了一段时间突然发现了一个思路, 不知道是否正确
import java.io.BufferedInputStream;
import java.util.Scanner;
public class Main {
/**
* 假设数组长度为n, 数组长度从0到n-1
* 定义子数组和为最大的数组为最大子数组A[i, j]
* 即子数组从i出发到j
*
* 分析可知道本题最大子数组和产生的情况只有两种
*
* 第一种情况是普通的最大子数组和问题
* 即i <= j
* 第二种情况是i > j
* 针对这种情况, 可以理解为从数组A中截取掉
* A[j+1, i-1]部分,使得剩下数组和最大
* 那么问题可以转化为求数组的最小子数组和
* 下面是针对上面分析的代码
*/
public static void main(String[] args) {
Scanner cin = new Scanner(new BufferedInputStream(System.in));
while (cin.hasNext()) {
int n = cin.nextInt();
int minSum = 0;
int maxSum = 0;
int maxSub = 0;
int minSub = 0;
int total = 0;
for(int i=0; i<n; i++) {
int value = cin.nextInt();
total += value;
maxSum += value;
if (maxSum > maxSub) {
maxSub = maxSum;
}
if (maxSum < 0) {
maxSum = 0;
}
// 求最小子数组和
minSum += value;
if (minSum < minSub) {
minSub = minSum;
}
if (minSum > 0) {
minSum = 0;
}
}
System.out.println(Math.max(maxSub, total - minSub));
}
cin.close();
}
}