k大小的子序列之差的最小值的最大值

时间:2018-11-07 22:21:08

标签: arrays algorithm subsequence

给出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个长度的子序列,然后在每个子序列中找到最小值,然后在所有它们中找到最大值,但是由于约束条件而超时。

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

有人可以提供最佳且更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

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

关键观察是这个。很容易从最小间隔至少为m的第一个元素开始构造最紧凑的序列。只要取第一个元素,并且当其至少比您取的最后一个大m大时,彼此取个。因此,我们可以编写一个构造此序列并跟踪3个数字的函数:

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

对于您的序列,如果我们以2的间隔进行此操作,我们会发现我们采用了3个元素,最小的间隔为3,如果我们寻找的间隔为2,我们将得到一个不同的序列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)个空缺,因此我们保证只需要很多次即可。