如何在循环链表中找到最大子序列和

时间:2014-09-03 14:06:39

标签: java algorithm

我知道最大子阵列和问题及其O(n)算法。此问题通过使用循环链表修改了该问题:

在最大总和的圆形链表中查找数字序列。
现在,如果所有条目的总和为零,该怎么办?

对我来说,唯一的方法是修改数组解决方案并让算法循环,并在第一次迭代完成后从列表的开头重新开始。然后对整个列表执行相同的操作最多2次并找到最大值。不好的一面是,如果我这样做,可能会有很多非常棘手的问题,例如,如果列表如下:

2 - 2 - 2 - 2回到前面

然后两次不包含相同的元素非常棘手

有更好的算法吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

首先,如果数据结构是链表或数组并不重要,所以为了简单起见,我将使用数组。

我不太了解你的算法,但似乎你要做的事情就像在原版后面复制数组一样,然后在这个加倍的情况下运行Kadane&#39的算法-array 即可。这是一种错误的方法,@ RanaldLam给出了一个反例。

要解决这个问题,我们需要在三种情况下进行讨论:

  1. 全部否定。在这种情况下,数组的最大值就是答案,O(N)扫描将完成这项工作;
  2. 最大子数组不需要换行,例如a = {-1, 1, 2, -3}。在这种情况下,正常的Kadane算法将完成工作,时间复杂度O(N);
  3. 最大子数组需要换行,例如a = {1, -10, 1}。实际上,这种情况意味着另一个事实:由于最大子数组中的元素需要包装,因此不在最大子数组内的元素不需要包装。因此,只要我们知道这些非贡献元素的总和,我们就可以通过从数组的总和中减去max_non_contributing_sum来计算贡献元素的正确总和。
  4. 但如何在案例3中计算max_non_contributing_sum?这有点棘手:因为这些非贡献元素不需要包装,所以我们可以简单地反转每个元素的符号并在此反向数组上运行Kadane算法,这需要{ {1}}。

    最后,我们应该比较非包装(案例2)和包装(案例3)的总和,答案应该是更大的答案。

    总结一下,所有案例都需要O(N),因此算法的总复杂度为O(N)

答案 1 :(得分:0)

你绝对正确。没有更好的算法。