我们如何输出标识最大子数组的索引j和k

时间:2018-10-03 07:57:43

标签: algorithm

最大子数组问题

给定一个由n个整数组成的数组,找到将总和最大化的子数组A [j:k]

Data

algorithm

要求: 我们如何输出索引j和k 识别最大子数组A [j:k]

请帮帮我 谢谢

2 个答案:

答案 0 :(得分:0)

我想到的第一个解决方案是:您可以使用如下所示的对象来代替在M中存储单个值:

 struct M {
        float sum,
        int start_index,
        int end_index
    }

现在如下更改您的算法以使用M对象:

Algorithm MaxSubFastest2(A):
    M[0] = {0, 1, 0}
    for t in 1 to n do:
        if M[t-1]+A[t] > 0:
            M[t] = {M[t-1]+A[t], M[t-1].start_index, M[t-1].end_index+1}
        else:
           M[t] = {0, 1, 0}
    m = 0
    start_index = 0
    end_index = 0
    for t in 1 to n do:
        if M[t].sum > m:
            m = M[t].sum
            start_index = M[t].start_index
            end_index = M[t].end_index

    if start_index <= end_index:
        subarray exists => return m, start_index, end_index
    subarray does not exist => error

此算法的时间复杂度与上述相同,但会占用额外的内存

更多内存优化版本在这里:

Algorithm MaxSubFastest3(A):
    max_so_far = 0
    max_ending_here = 0
    start =0
    end = 0
    s=0

    for i in 1 to n: 
        max_ending_here += A[i]
        if max_so_far < max_ending_here:
            max_so_far = max_ending_here
            start = s
            end = i

        if max_ending_here < 0:
            max_ending_here = 0
            s = i + 1
    output max_so_far, start, end

这与所讨论的时间和时间相同。

您可以找到同一算法here的其他变体。

另外,我注意到您对问题给出的算法将始终为包含-ve数字的列表的总和生成0。我不知道这是否是预期的行为。

答案 1 :(得分:0)

您可以为此使用最受欢迎的算法Kadanes Algorithm

如算法所述,我假设传递给它一个非空数组。然后,我使用两个变量prevcurr

来简单地跟踪最大和开始和结束的索引
int maxsubarray(int arr[])
{
    int maxsofar = arr[0], sum = arr[0], prev = 0, curr = 0;
    for i = 1 to arr.size

      //number greater than the addition of sums
      if(nums[i] > sum + nums[i]) prev = i;

      //maximum sum till this point in the array
      sum = max(nums[i], sum + nums[i])

      // if this is better than what we have so far
      if(sum > maxsofar)
          //store this sum and the array value
          maxsofar = sum
          curr = i

    print "start index of sum:", prev
    print "end index of sum:", curr

    // return the maximum value also found so far
    return maxsofar;
}