我想编写一个函数ContigSum(i,j)
来计算连续元素a[i]
到a[j]
的总和,其中i<=j
和a[]
包含正数和负数号。
您能否告诉我一个时间有效的解决方案,找到阵列中最大化的连续SUM?
答案 0 :(得分:7)
在wikipedia entry中有关该主题的详细解释。我发现他们为Kandane的算法提供的Python代码(即可执行的伪代码)是一个小宝石:
def max_subarray(A):
max_so_far = max_ending_here = 0
for x in A:
max_ending_here = max(0, max_ending_here + x)
max_so_far = max(max_so_far, max_ending_here)
return max_so_far
答案 1 :(得分:2)
Jon Bentley在第一版第7栏或第2版“Programming Pearls”第8栏中对此进行了讨论。
答案 2 :(得分:1)
Alex,你有一个非常优雅的算法但它需要修正一个包含单个元素的数组。
当然,在Kadane的原始算法中,可以得到子阵列的开始和结束索引,这对于了解“路径”很有用。
这是一个不优雅但我认为正确的Python功能:
def max_subarray(A):
(maxSum, maxStartIndex, maxEndIndex) = (float("-inf"), 0, 0)
(currentMaxSum,currentStartIndex,currentEndIndex ) = (0,0,0)
for item in A:
currentMaxSum = currentMaxSum + item
if currentMaxSum > maxSum :
(maxSum, maxStartIndex, maxEndIndex) = (currentMaxSum, currentStartIndex, currentEndIndex)
if currentMaxSum < 0 :
currentMaxSum = 0
currentStartIndex = currentEndIndex + 1
# continue here.
currentEndIndex = currentEndIndex + 1
return (maxSum, maxStartIndex, maxEndIndex)
答案 3 :(得分:0)
static void MaxContiguousSum(int[] x, int lb, int[] result)
{
int start, end, sum, testSum;
start = lb;
end = lb;
/* Empty vector has 0 sum*/
sum = 0;
testSum = 0;
for (int i=lb; i < x.length; i++)
{
if (sum + x[i] < 0)
{
/* Net contribution by current term is negative. So, contiguous sum lies in [start,i-1]
or [i+1, array upper bound]*/
MaxContiguousSum(x, i+1, result);
if (result[0] < sum)
{
result[0] = sum;
result[1] = start;
result[2] = end;
}
return;
}
else
{
testSum += x[i];
if (testSum > 0)
{
/* Move the end marker since incrementing range is beneficial. */
end = i;
/* update the sum*/
sum += testSum;
/* reset the testSum */
testSum = 0;
}
}
}
/* Update the results */
result[0] = sum;
result[1] = start;
result[2] = end;
return;
}
答案 4 :(得分:0)
这是正确的Java代码,它将处理包括所有负数的方案。
public static long[] leftToISumMaximize(int N, long[] D) {
long[] result = new long[N];
result[0] = D[0];
long currMax = D[0];
for (int i = 1; i < N; i++) {
currMax = Math.max(D[i], currMax + D[i]);
result[i] = Math.max(result[i - 1], currMax);
}
return result;
}
答案 5 :(得分:0)
这是我刚刚在Visual Studio 2012上实现和测试的C ++代码。
int maxSum(int *A, int lo, int hi) {
int left = lo, right = lo, sum = INT_MIN, currentMaxSum = 0, maxLeft = lo, maxRight = lo;
for(int i = lo; i < hi; i++) {
currentMaxSum += A[i];
if(currentMaxSum > sum) {
sum = currentMaxSum;
right = i;
maxLeft = left;
maxRight = right;
}
if(currentMaxSum < 0) {
left = i+1;
right = left;
currentMaxSum = 0;
}
}
printf("Maximum sum contiguous subarray :");
for(int i = maxLeft; i <= maxRight; i++)
printf(" %d", A[i]);
printf("\n");
return sum;
}
下面是调用上述函数的main()代码。
int main() {
int A[] = {3,-4, -3, 2, 6};
int N = sizeof(A) / sizeof(int);
printf("Maximum sum : %d\n", maxSum(A, 0, N));
return 0;
}
答案 6 :(得分:0)
这是我在Ruby中的解决方案。返回O(n)时间和O(1)内存中的最大连续子。我也是,为了以防万一,写了一些单元测试;)
def largest_contiguous_subsum(array)
max_sum = 0
current_sum = 0
array.each do |num|
current_sum += num
max_sum = current_sum if current_sum >= max_sum
current_sum = 0 if current_sum < 0
end
return max_sum
end