Kadane's algorithm (http://en.wikipedia.org/wiki/Maximum_subarray_problem) is used to find the largest sum of contiguous sub-array within a one-dimensional array of numbers.

Now, how this be used to find out the number of such sequences that have the same largest sum? What modifications can be done to the algorithm to count such sequences..

For eg:

0 0 0 1     -> (largest sum = 1); 4 sequences  { (0,0,0,1), (0,0,1), (0,1) , (1) }

0 0 0       -> (largest sum = 0); 6 sequences { (0,0,0), (0,0), (0,0), (0), (0), (0) }

2 0 -2 2    -> (largest sum = 2); 4 sequences { (2), (2,0), (2,0,-2, 2), (2) }
有帮助吗?

解决方案

Kadane's algorithm keeps track of the maximum value of a sequence ending at the current point, and the maximum value seen so far.

Here is a Python implementation based on the wikipedia page:

def kadane(A):
    max_ending_here = max_so_far = 0
    for x in A:
        max_ending_here = max([x,0,max_ending_here+x])
        max_so_far = max(max_so_far,max_ending_here)
    return max_so_far

We can modify the algorithm to keep track of the count of such sequences by adding two variables:

  • count_with_max_ending_here to count the number of sequences ending at the current point with values that sum to max_ending_here
  • count_with_max to count the number of sequences found so far with the maximum value

Kadane's algorithm can be straightforwardly changed to keep track of these variables while staying at O(n) complexity:

def kadane_count(A):
    max_ending_here = max_so_far = 0
    count_with_max_ending_here = 0 # Number of nontrivial sequences that sum to max_ending_here
    count_with_max = 0
    for i,x in enumerate(A):
        new_max = max_ending_here+x
        if new_max>=0:
            if count_with_max_ending_here==0:
                # Start a nontrivial sequence here
                count_with_max_ending_here=1
            elif max_ending_here==0:
                # Can choose to carry on a nontrivial sequence, or start a new one here
                count_with_max_ending_here += 1
            max_ending_here = new_max
        else:
            count_with_max_ending_here = 0 
            max_ending_here = 0

        if max_ending_here > max_so_far:
            count_with_max = count_with_max_ending_here
            max_so_far = max_ending_here
        elif max_ending_here == max_so_far:
            count_with_max += count_with_max_ending_here

    return count_with_max

for A in [ [0,0,0,1],[0,0,0],[2,0,-2,2] ]:
    print kadane(A),kadane_count(A)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top