数组中数字的均匀分布

时间:2018-09-09 23:09:00

标签: algorithm language-agnostic

我的问题是我有一个给定的1到100之间的n个数字数组。目标是选择5个数字,以使总距离最小。总距离是通过将初始数组中每个数字与5个选取数字中最接近的数字的距离相加得出的。

我(有点)尝试过并想到的:

  • 将数组的平均数除以5得到有用的东西吗?
  • 将数组长度除以5,即数字x,然后第一个数字是array [x],第二个数字是array [x * 2],依此类推

示例

  • 输入[5,10,15,20,...,85,90,95,100]
  • 输出[10、30、50、70、90] (可能会有更好的输出,但是我希望这可以使目标明确)

您可以看到我很迷茫,只是无法提出解决方案。对此可能有一个超级简单的解决方案,我只是不明白。

我只是在寻找一个提示,而不是解决方案,我不会自己弄清楚。

1 个答案:

答案 0 :(得分:1)

这是一种可以在多项式时间内工作的算法。

首先,对您的n数组进行排序。接下来,计算一个2维数组,其中每个0 <= i <= j < n都包含最佳元素的索引,以填充从第i个元素到第j个元素的范围。从该最佳数组中为每个间隔填写一个相似的总距离数组。

以上面的示例输出为例,第一个2维数组看起来像:

optimal_index = [
    [ 0,  0,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9],
    [ 1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10],
    [ 2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10],
    [ 3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11],
    [ 4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11],
    [ 5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12],
    [ 6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12],
    [ 7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 13],
    [ 8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 13, 13],
    [ 9,  9, 10, 10, 11, 11, 12, 12, 13, 13, 14],
    [10, 10, 11, 11, 12, 12, 13, 13, 14, 14],
    [11, 11, 12, 12, 13, 13, 14, 14, 15],
    [12, 12, 13, 13, 14, 14, 15, 15],
    [13, 13, 14, 14, 15, 15, 16],
    [14, 14, 15, 15, 16, 16],
    [15, 15, 16, 16, 17],
    [16, 16, 17, 17],
    [17, 17, 18],
    [18, 18],
    [19],
]

其中,从ij的范围内的最佳元素的索引为optimal_index[i][j-i]。使用相同的索引编制方案,成本矩阵将为:

optimal_cost = [
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180, 210, 245, 280, 320, 360, 405, 450, 500],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180, 210, 245, 280, 320, 360, 405, 450],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180, 210, 245, 280, 320, 360, 405],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180, 210, 245, 280, 320, 360],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180, 210, 245, 280, 320],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180, 210, 245, 280],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180, 210, 245],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180, 210],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150, 180],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125, 150],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100, 125],
    [ 0, 5, 10, 20, 30, 45, 60, 80, 100],
    [ 0, 5, 10, 20, 30, 45, 60, 80],
    [ 0, 5, 10, 20, 30, 45, 60],
    [ 0, 5, 10, 20, 30, 45],
    [ 0, 5, 10, 20, 30],
    [ 0, 5, 10, 20],
    [ 0, 5, 10],
    [ 0, 5],
    [ 0],
]

现在如果我们用2个元素填充范围怎么办?这是一个采用每个范围,并查看每个点的成本的问题,我们可以将其划分。该新数据结构只需要包含在“最接近第一个元素”和“最接近第二个元素”之间分开的位置。从该划分中,我们可以取任意范围,然后迅速将其划分为最优2,然后告诉您两个选定的元素是什么以及总成本。可以用类似的矩阵填充。请注意,先前的optimal_cost矩阵将使这些计算非常简单。

接下来,具有4个元素的范围又如何呢?这与2个元素的范围完全相同,除了,我们现在在第一对和第二对之间进行划分。但是逻辑是一样的。

最后,关于5个元素的问题呢?这只是计算最接近前四个元素和最接近最后一个元素之间最佳划分的问题。因此,只需尝试所有可能性。

将其k填充为大小为n的数组的自然概括是O(n^3 log(k))