我试图通过解决Codality问题来提高我的技能。我达到了这个:https://codility.com/programmers/lessons/9-maximum_slice_problem/max_double_slice_sum/
我实际上理论上理解解决方案:
我的问题不在于如何解决问题。我的问题是如何想象这将成为解决这个问题的方法。至少有3个不同的概念需要使用:
理解如果数组中的所有元素都是正数或负数,则与数组中存在一些正面和负面元素的情况不同。
Kadane的算法
向前移动阵列并反转。
尽管如此,Codality已将此问题标记为"无痛"。
我的问题是我错过了什么?在不了解其中一些概念的情况下,我似乎很难解决这个问题。
是否有一种技术可以让我从头开始和非常基本的概念,并努力解决这个问题所需的概念。或者在我开始问题之前我是否应该知道这些概念?
我如何准备好自己解决这些问题,而我将来不知道所需的概念?
答案 0 :(得分:2)
我认为你正在思考这个问题,这就是为什么你发现它比现在更困难的原因:
理解如果数组中的所有元素都是正数或负数,则与数组中存在一些正面和负面元素的情况不同。
不一定是另一种情况。您或许可以提出一种不关心这种区别的算法并且无论如何都可以工作。
你不需要从理解这种区别开始,所以在你需要之前不要考虑它。
卡丹的算法
不要考虑算法,想一想问题需要什么。通常,10+段问题陈述可以用更少的表达来表达。
让我们看看我们如何简化问题陈述。
它首先将切片定义为三元组(x, y, z)
。它是从x+1
开始,以z-1
结尾而不包含y
的元素总和定义的。
然后它要求最大总和切片。如果我们需要最大切片,那么定义中是否需要x
和z
?我们不妨让它在任何地方开始和结束,只要它能得到我们的最大金额,不是吗?
因此,将切片重新定义为从任何地方开始的数组的子集,上升到某个y-1
,从y+1
继续并在任何地方结束。更简单,不是吗?
现在你需要最大的切片。
现在您可能认为,对于每个y
,您需要从y+1
开始的最大和子数组以及以y-1
结尾的最大和子数组。如果您能找到这些,则可以更新每个y
的全局最大值。
那你怎么做的?现在,这应该指向Kadane的算法,该算法可以实现您想要的一半:它计算以某些x
结尾的最大和子数组。因此,如果您从双方计算它,对于每个y
,您只需要找到:
kadane(y - 1) + kadane_reverse(y + 1)
与全球最大值进行比较
没有负面和正面的特殊情况。没想到“Kadane的!”一旦你看到问题。
这个想法是在不改变其含义的情况下尽可能简化要求。然后,您使用算法和演绎技巧来达成解决方案。这些技能随着时间和经验而磨练。