// 题目:给出一个数组,求连续子数组的最大和
// 解法1:遍历每个子数组,求出组大的和,复杂度O(N^3),优化后复杂度O(N^2)
public class Main {
public static void main(String[] args) {
System.out.println(findNum1(new int[] { -5, 6, 8, -3, 7, -9, 4 }));
System.out.println(findNum2(new int[] { -5, 6, 8, -3, 7, -9, 4 }));
}
public static int findNum1(int[] input) { //时间复杂度O(N^3)
int maxSum = Integer.MIN_VALUE;
for(int i = 0;imaxSum){
maxSum = sum;
}
}
}
return maxSum;
}
public static int findNum2(int[] input){ //优化后的方法,时间复杂度O(N^2)
int maxSum = Integer.MIN_VALUE;
for(int i = 0;imaxSum){ //每次加一个元素就进行一次比较,这样可以考虑(2,3)这种情况
maxSum = sum;
}
}
}
return maxSum;
}
}
//解法2:分治法的思想,分为规模减半的子问题,通过递归解决;复杂度O(nlogn)
//解法3:建立两个数组,分别保存以当前数字结尾的子数组的最大和与从开头到这个数为止所有子数组的最大的最大和,时间复杂度O(N),空间复杂度O(N)
public class Main {
public static void main(String[] args) {
System.out.println(findNum(new int[] { -5, 6, 8, -3, 7, -9, 4 }));
}
public static int findNum(int[] input) {
int[] start = new int[input.length]; //保存以当前数字结尾的子数组的最大和
int[] allStart = new int[input.length]; //从开头到这个数为止所有子数组的最大的最大和
start[0] = input[0];
allStart[0] = input[0];
for(int i = 1;istart[i-1]+input[i]){ //如果上一个数的最大和加上当前数比当前数的值大,则start[i]变为相应的值
start[i] = input[i];
}else{
start[i] = start[i-1]+input[i];
}
if(start[i]>allStart[i-1]){ //如果当前元素为结尾的子数组的最大和大于之前所有的最大和,则相应更新allStart的值
allStart[i] = start[i];
}else{
allStart[i] = allStart[i-1];
}
}
return allStart[input.length-1];
}
}
//解法4:不用建立辅助空间了,也是采用动态规划的思想
public class Main {
public static void main(String[] args) {
System.out.println(findNum(new int[] { -5, 6, 8, -3, 7, -9, 4 }));
}
public static int findNum(int[] input) {
int max = input[0];
int totalMax = input[0];
int s = 0;
int e = 0;
for(int i = 1;itotalMax){
totalMax = max;
e = i;
}
}
System.out.println(s+" "+e); //返回最大子数组的起始和终止位置
return totalMax;
}
}