我正在做一些练习编程问题以准备面试。
其中一个问题如下:您试图找到将阵列切成两半的位置,这样每个半部的总和之间的差异就会最小化。可以实现的最小差异是什么?
所以
A[0] = 3
A[1] = 1
A[2] = 2
A[3] = 4
A[4] = 3
我们可以将这个磁带分成四个部分:
P = 1, difference = |3 − 10| = 7
P = 2, difference = |4 − 9| = 5
P = 3, difference = |6 − 7| = 1
P = 4, difference = |10 − 3| = 7
所以我们会返回1,因为这是最小的差异。
这很容易在n平方时间内完成,但问题指出它可以在n个时间内完成,有n个存储空间。任何人都可以推荐一个解决方案吗?我看待它的每一种方式,即使有额外的空间,你也必须继续沿阵列运行。您需要知道整个数组的值,然后才能选择哪个切割最小。
答案 0 :(得分:5)
通过两次O(n)
次传球可以找到中间切割位置。考虑一下你原来的问题:
A[0] = 3
A[1] = 1
A[2] = 2
A[3] = 4
A[4] = 3
迭代此数组值并在名为sums
的新数组中记录增量总和:
sums[0] = 3
sums[1] = 4
sums[2] = 6
sums[3] = 10
sums[4] = 13
在此迭代之后,还知道总和是多少,在这种情况下是13
。现在您需要做的就是遍历sums
数组并选择最接近的值 half 总和。在这种情况下,sums[2] = 6
符合条件,因此您可以将切割放在第三位。
sums[0] = 3
sums[1] = 4
sums[2] = 6
----------- <-- make the cut here
sums[3] = 10
sums[4] = 13
答案 1 :(得分:2)
有两个运行总和,一个从位置0开始,另一个从N开始。
从起始位置初始化总和。
比较两个和,如果第一个小于或等于一个,则向上推进第一个总和的光标位置,否则向下推进第二个和光标的位置。
检查您是否未到达另一笔的光标位置。 如果你有,退出循环,你有你的总和,你可以减去它们,以获得最小的差异。
如果没有将新值从新位置添加到适当的求和循环。