如何在数组中找到最大连续SUM(包含正数和负数)?

时间:2010-06-15 04:12:37

标签: algorithm

我想编写一个函数ContigSum(i,j)来计算连续元素a[i]a[j]的总和,其中i<=ja[]包含正数和负数号。

您能否告诉我一个时间有效的解决方案,找到阵列中最大化的连续SUM?

7 个答案:

答案 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