作者热门文章
- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想为给定的整数输入数组找到一个非空的连续子数组,它可以有重复的值。我尝试了分而治之的方法来查找一个数组的最大连续子数组,结果返回了与预期不同的结果。请在下面找到代码。
private static int maxSumRec(int[] a, int low, int high) {
int leftSum = 0, rightSum = 0;
int sum = 0;
if (low == high) { // Base case
return a[low];
}
int mid = (low + high) >> 1; // (low + high) / 2
int maxLeftSum = maxSumRec(a, low, mid);
int maxRightSum = maxSumRec(a, mid + 1, high);
//max-crossing-subarray
for (int i = mid; i >= low; i--) {
sum += a[i];
if (sum > leftSum) {
leftSum = sum;
}
}
sum = 0;
for (int i = mid + 1; i <= high; i++) {
sum += a[i];
if (sum > rightSum) {
rightSum = sum;
}
}
return max3(maxLeftSum, maxRightSum, (leftSum + rightSum));
}
private static int max3(int a, int b, int c) {
return a > b ? (a > c ? a : c) : (b > c ? b : c);
}
public static void main(String[] args) {
//INPUT
int a[] = {
-5, 71, 23, 41, 34, 1, 3, 6, 2, 91, 312, 42, 31, 67, 12, 10, 18, 56, 90, 21, 45, 47, 89, 1999999990,
78, -7, 76, 75, 74, 73, 72, 80, 24, 25, 61, 69, 84, 0, -1, 145, 1902, 200, 199, 198, 197, 196, 195, 194,
78, 77, 76, 75, 74, 73, 72, 80, 24, 25, 61, 69, 84, 0, -1, 145, 1902, 200, 199, 198, 197, 196, 195, 194,
5, 71, 23, 41, 34, 1, 3, 6, 2, 91, 312, 42, 31, 67, 12, 10, 18, 56, 90, 21, 45, 47, 89, 1999999990
};
int maxSum = maxSumRec(a, 0, a.length - 1);
System.out.println("Max sum is " + maxSum);
}
此代码返回的结果为 2000005400。 MCS 的非递归版本返回不同的结果,即 2000010721 及其从 {1-94} 中找到的结果。我无法弄清楚原因。如果代码中有错误,请告诉我。
最佳答案
1 到 95 的和(即 :4000010711 )实际上大于 1 到 94 的和。
您的整数
太长了。
您需要使用long
来获得正确的结果。
注意:
整数介于 -2147483648 和 2147483647 之间
int test=2147483647;
System.out.println(test);
System.out.println(test+1);
你会得到:
2147483647
-2147483648
试试这个:
public class Sample5 {
private static long maxSumRec(int[] a, int low, int high) {
long leftSum = 0, rightSum = 0;
long sum = 0;
if (low == high) { // Base case
return a[low];
}
int mid = (low + high)/2; // (low + high) / 2
long maxLeftSum = maxSumRec(a, low, mid);
long maxRightSum = maxSumRec(a, mid + 1, high);
//max-crossing-subarray
for (int i = mid; i >= low; i--) {
sum += a[i];
if (sum > leftSum) {
leftSum = sum;
}
}
sum = 0;
for (int i = mid + 1; i <= high; i++) {
sum += a[i];
if (sum > rightSum) {
rightSum = sum;
}
}
System.out.println("final left sum "+leftSum);
System.out.println("final right sum "+rightSum);
System.out.println("leftSum+rightSUM:"+(leftSum + rightSum));
return max3(maxLeftSum, maxRightSum, (leftSum + rightSum));
}
private static long max3(long a, long b, long c) {
return a > b ? (a > c ? a : c) : (b > c ? b : c);
}
private static int sum(int[] a,int i,int j){
int r=0;
for(int k=i;k<=j;k++){
r+=a[k];
}
return r;
}
public static void main(String[] args) {
//INPUT
int a[] = {
-5, 71, 23, 41, 34, 1, 3, 6, 2, 91, 312, 42, 31, 67, 12, 10, 18, 56, 90, 21, 45, 47, 89, 1999999990,
78, -7, 76, 75, 74, 73, 72, 80, 24, 25, 61, 69, 84, 0, -1, 145, 1902, 200, 199, 198, 197, 196, 195, 194,
78, 77, 76, 75, 74, 73, 72, 80, 24, 25, 61, 69, 84, 0, -1, 145, 1902, 200, 199, 198, 197, 196, 195, 194,
5, 71, 23, 41, 34, 1, 3, 6, 2, 91, 312, 42, 31, 67, 12, 10, 18, 56, 90, 21, 45, 47, 89, 1999999990
};
long maxSum = maxSumRec(a, 0, a.length-1);
System.out.println("Max sum is " + maxSum);
//WITH INTS
System.out.println("with ints, the sum 1 to 94 is " + sum(a,1,94));
System.out.println("with ints, the sum 1 to 95 is " + sum(a,1,95));
}
}
您将获得:
final left sum 2000005311
final right sum 2000005400
leftSum+rightSUM:4000010711
Max sum is 4000010711
with ints, the sum 1 to 94 is 2000010721
with ints, the sum 1 to 95 is -294956585
关于java - 分而治之最大连续子数组 (MCS) 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6997019/
我是一名优秀的程序员,十分优秀!