这种在连续子数组中找到最大和的递归算法有啥优势吗?

Posted

技术标签:

【中文标题】这种在连续子数组中找到最大和的递归算法有啥优势吗?【英文标题】:Does this recursive algorithm for finding the largest sum in a continuous sub array have any advantages?这种在连续子数组中找到最大和的递归算法有什么优势吗? 【发布时间】:2020-02-01 07:06:27 【问题描述】:

目标:评估在下面的连续子数组中找到最大和的算法。

注意:用 C++ 编写

当我研究 Kadane 使用动态编程成功解决的问题时,我想我会找到自己的解决方法。我通过使用一系列递归调用来做到这一点,具体取决于通过缩短数组的末端是否可以使总和更大。见下文。

int corbins_largest_sum_continuous_subarray(int n, int* array)
   int sum = 0; // calculate the sum of the current array given
   for(int i=0; i<n; i++)sum += array[i];

   if(sum-array[0]>sum && sum-array[n-1]>sum)
      return corbins_largest_sum_continuous_subarray(n-2, array+1);
   else if(sum-array[0]<sum && sum-array[n-1]>sum)
      return corbins_largest_sum_continuous_subarray(n-1, array);
   else if(sum-array[0]>sum && sum-array[n-1]<sum)
      return corbins_largest_sum_continuous_subarray(n-1, array+1);
   else 
      return sum; // this is the largest subarray sum, can not increase any further
   

我知道 Kadane 的算法需要 O(n) 时间。我在计算算法的大 O 时遇到问题。它也会是O(n)吗?因为它使用 O(n) 计算总和,之后的所有调用都使用相同的时间。我的算法比 Kadane 的算法有什么优势吗? Kadane 的算法在哪些方面更好?

【问题讨论】:

Kadane 算法的链接会有所帮助。 您总是在重新计算总和。最坏情况下的 O(N^2) 复杂度 此外,我不相信你的算法能提供好的结果。用 (1, -2, 5, -2, 1) 测试它 【参考方案1】:

首先,表达式sum-array[0]&gt;sum 等价于array[0]&lt;0。类似的观察结果适用于代码中的其他条件。

您的算法不正确。您在这里的评论不正确:

else
    return sum // this is the largest subarray sum, can not increase any further

当你到达那个点时,你知道外部的两个值都是正数,但在数组的其他地方可能有一个负和子数组,当被删除时,它会给出两个剩余的子数组,其中一个(或两者)的总和可能大于总和。

例如,以下输入就是这种情况:

[1, -4, 1]

您的算法将得出结论,通过取整个数组(总和为 -2)来实现最大总和,但子数组 [1] 表示更大的总和。

其他反例:

[1, 2, -2, 1]
[1, -3, -3, 1, 1]  

【讨论】:

以上是关于这种在连续子数组中找到最大和的递归算法有啥优势吗?的主要内容,如果未能解决你的问题,请参考以下文章

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

最大连续子段和的两种线性算法

最大连续子段和的两种线性算法

关于求已知整数数组的连续子数组的最大和的方法

牛客网:连续子数组的最大和(动态递归解法)

用动态规划算法求最大子序和