【问题标题】:maximum of minimum of difference in subsequence of k sizek 大小的子序列中差异的最大值和最小值
【发布时间】:2018-11-07 22:21:08
【问题描述】:

给定 n 个元素的排序序列。从长度为 k 的子序列的所有对差中找出所有最小值中的最大值。

Here 1<=n<=10^5
and 2<=k<=n

For eg: [2, 3, 5, 9] and k = 3
there are 4 subsequences:

[2, 3, 5] - min diff of all pairs = 1
[2, 3, 9] - min diff of all pairs = 1
[3, 5, 9] - min diff of all pairs = 2
[2, 5, 9] - min diff of all pairs = 3

所以答案是所有最小差异的最大值 = 3

天真的方法是找到所有 k 个长度的子序列,然后在每个子序列中找到最小值,然后在所有子序列中找到最大值,但由于限制,这将超时。

除此之外,我的想法是找到最佳距离的序列,以便最小值变为最大值。

有人能给出一个最佳和更好的解决方案吗?

【问题讨论】:

标签: arrays algorithm subsequence


【解决方案1】:

假设您的整数序列是a[i]。那么我的解决方案会及时找到答案O(n log((a[n-1]-a[0])/n))。如果您的序列是浮点数,它可能会在相似的时间内运行,但理论上可能与O(n^3) 一样糟糕。

关键的观察是这个。从最小间隙至少为m 的第一个元素开始构造最紧凑的序列很容易。只取第一个元素,当它至少比你取的最后一个元素大m 时,互相取一个。所以我们可以编写一个函数来构造这个序列并跟踪 3 个数字:

  1. 我们得到了多少元素
  2. 我们发现的最小间隙的大小。
  3. 下一个最小的m 将导致更紧凑的序列。也就是说,与我们未包含的元素的最大差距。

对于您的序列,如果我们以 2 的间隙执行此操作,我们会发现我们采用了 3 个元素,最小的间隙是 3,如果我们寻找间隙,我们会得到一个不同的序列1.

这些信息足以构建所需间隙长度的二分搜索。关键逻辑如下所示:

lower_bound = 0
upper_bound = (a[n-1] - a[0])/(k-1)
while lower_bound < upper_bound:
    # Whether int or float, we want float to land "between" guesses
    guess = (lower_bound + upper_bound + 0.0) / 2
    (size, gap_found, gap_different) = min_gap_stats(a, guess)
    if k < size:
        # We must pick a more compact sequence
        upper_bound = gap_different
    else:
        # We can get this big a gap, but maybe we can get bigger?
        lower_bound = gap_found

如果我们为您的序列运行此操作,我们首先将 lower_bound 设置为 0,将 upper_bound 设置为 7/2 = 3(感谢整数除法)。我们会立即找到答案。

如果您有一系列具有相同值的浮点数,则需要更长的时间。我们首先尝试 3.5,并在 3 处获得不同决定的 2 序列。然后我们将尝试 1.5,并找到我们想要的间隙的 3 序列。

二分查找通常会使它采用对数的遍数。 然而,每次我们将上限或下限设置为实际成对间隙的大小。由于只有O(n^2) 间隙,因此我们保证不需要超过那么多遍。

【讨论】:

  • 由于限制,上述问题的解决方案应该在最坏的情况下运行 O(nlogn)。那么任何人都可以帮助我吗?。
  • @user1818277 您将不得不努力寻找在最坏情况下无法运行的示例O(n log(n))。但是从实际差距中随机选择支点会使得没有一个确定性不好。但平均而言,这会更慢。
  • 您的算法最坏情况是 O(nlogn) ?如果是这样,那很好,否则需要提出一些不同的算法
  • @user1818277 我知道怎么去O(n log(n))。解释它将是一个熊,而且努力是不值得的。如果你想弄清楚,你可以先阅读快速选择,然后是中位数的中位数,然后你需要运用聪明才智——所有这些都是从实际差距中选择一个支点的最后,以这样一种方式,你保证得到正确的结果。完成这项工作后,它的平均运行速度会慢得多。
  • 如果您的数字是 32 位整数,您一定会在~30 通行证中得到答案。 (如果 k 很大,则更少。)使用 64 位整数,即 ~60 通过。这些通行证将比“理论上正确”的解决方案快得多。
猜你喜欢
  • 2022-12-20
  • 1970-01-01
  • 2017-08-15
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-04
相关资源
最近更新 更多