我知道最大子阵列和问题及其O(n)算法。此问题通过使用循环链表修改了该问题:
在最大总和的圆形链表中查找数字序列。
现在,如果所有条目的总和为零,该怎么办?
对我来说,唯一的方法是修改数组解决方案并让算法循环,并在第一次迭代完成后从列表的开头重新开始。然后对整个列表执行相同的操作最多2次并找到最大值。不好的一面是,如果我这样做,可能会有很多非常棘手的问题,例如,如果列表如下:
2 - 2 - 2 - 2回到前面
然后两次不包含相同的元素非常棘手
有更好的算法吗?
谢谢!
答案 0 :(得分:2)
首先,如果数据结构是链表或数组并不重要,所以为了简单起见,我将使用数组。
我不太了解你的算法,但似乎你要做的事情就像在原版后面复制数组一样,然后在这个加倍的情况下运行Kadane&#39的算法-array 即可。这是一种错误的方法,@ RanaldLam给出了一个反例。
要解决这个问题,我们需要在三种情况下进行讨论:
O(N)
扫描将完成这项工作; a = {-1, 1, 2, -3}
。在这种情况下,正常的Kadane算法将完成工作,时间复杂度O(N)
; a = {1, -10, 1}
。实际上,这种情况意味着另一个事实:由于最大子数组中的元素需要包装,因此不在最大子数组内的元素不需要包装。因此,只要我们知道这些非贡献元素的总和,我们就可以通过从数组的总和中减去max_non_contributing_sum来计算贡献元素的正确总和。但如何在案例3中计算max_non_contributing_sum
?这有点棘手:因为这些非贡献元素不需要包装,所以我们可以简单地反转每个元素的符号并在此反向数组上运行Kadane算法,这需要{ {1}}。
最后,我们应该比较非包装(案例2)和包装(案例3)的总和,答案应该是更大的答案。
总结一下,所有案例都需要O(N)
,因此算法的总复杂度为O(N)
。
答案 1 :(得分:0)
你绝对正确。没有更好的算法。