首先,数据结构是链表还是数组并不重要,所以为了简单起见,我将使用数组。
我并不十分理解你的算法,但似乎你要做的事情就像在原始数据的后面重复数组,然后在这个doubled-array上运行Kadane的算法。这是一个错误的方法,@RanaldLam给出了一个反例。
为了解决这个问题,我们需要讨论的三种情况:
- 均为阴性。在这种情况下,数组的最大值就是答案,并且
O(N)
扫描将完成这项工作;
- 最大子数组不需要换行,例如
a = {-1, 1, 2, -3}
。在这种情况下,正常的Kadane算法可以完成这项工作,时间复杂度为O(N)
;
- 最大的子阵列需要打包,例如
a = {1, -10, 1}
。实际上,这种情况意味着另一个事实:由于最大子数组内的元素需要打包,因此不在最大子数组内的元素不需要打包。因此,只要我们知道这些非贡献元素的总和,就可以通过从数组总和中减去max_non_contribute_sum来计算贡献元素的正确总和。
但是如何计算案例3中的max_non_contributing_sum
?这有点棘手:因为这些不贡献的元素不需要包装,所以我们可以简单地反转每个元素的符号,并在该反转阵列上运行Kadane的算法,这需要O(N)
。
最后,我们应该比较非包装(情况2)和包装(情况3)的总和,答案应该是较大的一个。
总结,所有案例都需要O(N)
,因此该算法的总体复杂度为O(N)
。
通过打开环并复制除最后一个元素之外的所有元素,可将圆形问题转换为标准线性问题,并保持O(N)行为。 [其实你不需要复制这些元素,只需以模N来访问它们。] – 2014-09-03 14:15:47
如果数组完全正向会怎么样?例如:{1,2,3,4,5}。在第一次迭代后不会从头开始重复给出1 + 2 + 3 + 4 + 5 + 1 + 2 + 3 + 4 + 5 = 30,答案是15?或者我误解了你的方法>< – 2014-09-03 15:04:48
是它的子序列还是子阵?注意到,子序列不需要**连续的数字**,但是子数组就是这样。 – nevets 2014-09-03 17:53:07