【发布时间】:2020-02-02 17:13:42
【问题描述】:
我正在尝试为下一个问题找到 O(N) 的分治法解决方案:
给定一个循环排序数组,我需要正数之和。即:
If the array is: {-2, 0, 3, 4, 11, 13, -23, -15, -8}
Then the algorithm should return 31.
我想我用下面的代码很接近它,但它奇怪地返回 -17 并且我找不到问题调试:
public class Main {
private static final int[] TEST_VECTOR = new int[]{-2, 0, 3, 4, 11, 13, -23, -15, -8};
public static int sumPositives2(int[] vector) {
return maximumSum(vector,0, vector.length - 1);
}
// Function to find Maximum subarray sum using
// divide and conquer
public static int maximumSum(int[] A, int left, int right)
{
// If array contains only one element
if (right == left) {
return A[left];
}
// Find middle element of the array
int mid = (left + right) / 2;
// Find maximum subarray sum for the left subarray
// including the middle element
int leftMax = Integer.MIN_VALUE;
int sum = 0;
for (int i = mid; i >= left; i--)
{
if(A[i] > 0) {
sum += A[i];
}
}
// Find maximum subarray sum for the right subarray
// excluding the middle element
int rightMax = Integer.MIN_VALUE;
sum = 0; // reset sum to 0
for (int i = mid + 1; i <= right; i++)
{
if(A[i] > 0) {
sum += A[i];
}
}
// Recursively find the maximum subarray sum for left
// subarray and right subarray and tale maximum
int maxLeftRight = maximumSum(A, left, mid) +
maximumSum(A, mid + 1, right);
// return maximum of the three
return maxLeftRight + leftMax + rightMax;
}
public static void main(String[] args)
{
System.out.println("The Maximum sum of the subarray is " +
maximumSum(TEST_VECTOR, 0, TEST_VECTOR.length - 1));//Should be 31
}
}
编辑:这个解决方案会是 O(N) 吗?
感谢您的宝贵时间。
【问题讨论】:
-
由于您需要遍历所有数字才能获得总和(如果所有数字都是正数),则至少需要 O(N) 时间。
-
我不确定这段代码在做什么,而且似乎有很多缺陷。例如,整个第一个循环没有影响,因为计算了
sum,但在使用之前它被设置回 0。leftMax和rightMax都不会更改。停止子句在返回元素之前不检查元素是正数还是负数。 -
但是考虑到它是循环排序的,我猜应该有一种方法可以通过攻击“中间”值来获得 O(log N)
-
我的建议是从头开始。一步一步做。从一个没有分而治之的可行解决方案开始,然后尝试看看如何使用它(不确定是否有这样做的理由,但如果你坚持练习 - 没关系)。
-
@dev 攻击?你能告诉我
2, 3, _, 1的总和吗?它也是循环排序的。很明显,如果您不知道空白的值,我要求您做的事情是不可能的。期望计算机能够在 log n 操作中执行此操作是相同的原则。
标签: java arrays algorithm sorting divide-and-conquer