求解最大双片卡达内算法变化



我试图通过解决协同性问题来提高我的技能。我找到了这个:https://codility.com/programmers/lessons/9-maximum_slice_problem/max_double_slice_sum/

我实际上从理论上理解了解决方案:

  1. 对数组使用Kadane算法,并在每个索引处存储总和
  2. 反转数组并执行相同操作
  3. 通过一次循环一个结果集,找到两者之和为最大的点
  4. 最大值是最大双切片

我的问题与其说是关于如何解决这个问题。我的问题是,人们如何想象这将是解决这个问题的方法。至少有3个不同的概念需要使用:

  1. 如果数组中的所有元素都是正的或负的,则与数组中有一些正元素和负元素时的情况不同。

  2. Kadane算法

  3. 向前和反向越过阵列。

尽管如此,Codality还是将这个问题标记为"无痛"。

我的问题是我错过了什么吗?我似乎很难在不了解这些概念的情况下解决这个问题。

有没有一种技术可以让我从零开始,从非常基本的概念开始,逐步达到解决这个问题所需的概念。还是说,在开始问题之前,我就应该知道这些概念?

当我不知道未来需要的概念时,我该如何为自己解决这些问题做好准备?

我认为你想得太多了,这就是为什么你发现它比实际更困难的原因:

如果数组中的所有元素都是正的或负的,则与数组中有一些正元素和负元素时的情况不同。

这不一定是另一种情况。你也许可以想出一种算法,它不在乎这种区别,而且无论如何都能工作。

你不需要从理解这种区别开始,所以在必要的时候不要去想它

Kadane算法

不要想算法,要想问题需要什么。通常,10多段的问题陈述可以用更少的语言表达。

让我们看看如何简化问题陈述。

它首先将切片定义为三元组(x, y, z)。它定义为从x+1开始、到z-1结束且不包含y的元素的总和。

然后它要求最大和片。如果我们需要最大切片,那么我们在定义中需要xz吗?我们不妨让它在任何地方开始和结束,只要它能给我们最大的总和,不是吗?

因此,将切片重新定义为数组的子集,该子集从任何地方开始,一直到某个y-1,从y+1开始,在任何地方结束。简单多了,不是吗?

现在你需要这样的最大切片。

现在您可能认为,对于每个y,您需要从y+1开始的最大和子数组和从y-1结束的最大和个子数组。如果你能找到这些,你可以为每个y更新一个全局最大值。

你是怎么做到的?这应该会让你看到Kadane的算法,它完成了你想要的一半:它计算以某个x结尾的最大和子数组。因此,如果你从两侧计算,对于每个y,你只需要找到:

kadane(y - 1) + kadane_reverse(y + 1)

并与全球最大进行比较

阴性和阳性没有特殊情况。不要一看到问题就想着"卡丹的!"。

其想法是在不改变其含义的情况下尽可能简化需求。然后你用你的算法和演绎技巧来达成一个解决方案。这些技能是经过时间和经验磨练的。

最新更新