【问题标题】:Finding the position to cut an array in half, such that the difference of the sums is minimal找到将数组切成两半的位置,使得总和的差异最小
【发布时间】:2015-11-12 02:49:11
【问题描述】:

我正在做一些练习编程问题以准备面试。

其中一个问题如下:您正试图找到将数组切成两半的位置,以使每一半之和之间的差异最小化。可以实现的最小差异是多少?

所以

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 个存储空间。 谁能推荐一个解决方案?我看它的每一种方式,即使有额外的空间,你也必须继续沿着阵列运行。您需要知道整个数组的值,然后才能做出最小切割的选择。

【问题讨论】:

    标签: arrays algorithm big-o


    【解决方案1】:

    有两个运行总和,一个从位置 0 开始,另一个从 N 开始。

    从起始位置初始化总和。

    比较两个和,如果第一个小于或等于一个,则将第一个和的光标位置向上移动,否则将第二个和的光标位置向下移动。

    检查您是否尚未到达其他总和的光标位置。 如果你有,退出循环,你有你的总和,你可以减去它们以获得最小的差异。

    如果不将新位置的新值添加到适当的求和和循环中。

    【讨论】:

      【解决方案2】:

      通过两次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 数组并选择与总和的最接近 一半 的值。在这种情况下,sums[2] = 6 符合要求,因此您可以排在第三位。

      sums[0] = 3
      sums[1] = 4
      sums[2] = 6
      -----------      <-- make the cut here
      sums[3] = 10
      sums[4] = 13
      

      【讨论】:

      • 我误以为O(2n) == O(n^2)。你的答案很完美,因为第二次通过仍然在O(n) 预期的复杂性范围内。谢谢!
      猜你喜欢
      • 1970-01-01
      • 2015-10-08
      • 2020-04-07
      • 2021-03-22
      • 1970-01-01
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 2019-02-17
      相关资源
      最近更新 更多