繁体   English   中英

找到两个元素之间的最大距离,这两个元素的差异不超过k

[英]Find the maximum distance between two elements that don't differ by more than k

给定一个数组arr,找到最大的abs(ij),使得abs(arr [i] - arr [j])<= k。

经过深思熟虑后,我想出了以下算法,

1) Create a new array of pair<arr[i], i> (say arrayIndexPairs)
2) Sort this arrayIndexPairs based on the array value (first of pair).
3) Build a segment tree on the index (second of pair) with the arrayIndexPairs so that we can answer range max queries
4) for i <- 0 to n-1
    4.1) rightIndex = Binary search the array values (first of pair) for ceil(arrayIndexPairs[i].first) in the interval [i+1, n-1]
    4.2) int maxIndex = rangeQueryForMax(i+1, rightIndex)
    4.3) result = max(result, maxIndex - i);
return result

对于我们进行二元搜索O(log n) + rangeQueryO(log n)每个元素,复杂度为O(n log n) O(log n) 总时间复杂度为O(nlogn + n*2*logn) ,其渐近为O(nlogn)

方法是否正确? 有可能制定线性时间解决方案吗? 我尝试使用散列图,但很难找到线性解决方案。

我想出了这个:

def find_max_abs(l, k):
    for lenght_of_interval in range(len(l), 1, -1):
        for start_of_interval in range(0, len(l) - lenght_of_interval + 1):
            if abs(l[start_of_interval] - l[start_of_interval + lenght_of_interval - 1]) <= k:
                return lenght_of_interval - 1

应该很好地工作,但它不是线性的(最坏的情况是N²)。 如果存在线性算法,我感兴趣

对于一般情况,您的想法似乎很有效。

对于元素都是整数的情况,您可以在Θ(nk)预期时间内完成。 如果k = o(log(n))这是一个保存 如果k是常数,则n是线性的。

  1. 将所有元素放在一个哈希表中,将每个元素e映射到它在数组i中的位置(如果有多个e ,让你在哈希表中放置的每个条目都覆盖前一个 - 这没关系)。

  2. 对于位置i处的每个元素e ,以及d = -k, - (k-1),... 0,1,... k ,检查e + d是否在哈希表中。 如果是这样,你就可以从哈希表中获得e + d的位置,比如j

  3. 保留2中找到的最大距离的位置。

似乎有点强迫“线性”的定义。 我会以不同的方式接近。 我们可以注意到函数距离d正在搜索最大值。 所以我们知道有以下组合: - DIST COUPLES COUNT

  • d = n-1(a [0],a [n-1])1

  • d = n-2(a [0],a [n-2]),(a [1],a [n-1])2

  • ...
  • d = 1(a [0],a [1])...(a [n-2],a [n-1])n-1

由于我们搜索最大值,我们将首先通过最大距离进行调查。 所以我们有最好的情况O(1),最坏的情况是从1到n-1 =(n-1)*(n / 2)= O(n2)之和。 平均我期望更好的表现,因为它可以非常有效地实施。
这里的C实现:

#include "stdio.h"
#include "stdlib.h"
#define ARRAYSIZE 10000

int find_dist(int * result, const int *array, int n,int k )
{
  int i,j,ti;
  for (i=n-1;i>0;i--)
  { 
     ti=i;       
     for (j=0;ti< n ; j++,ti++)
        if (abs(array[j]-array[ti])<=abs(k))
            {
                result[0]=j;
                result[1]=ti;
                return 1;
            }
   }
return 0;
}

int main()
{
  int array[ARRAYSIZE],result[2],i;
  for (i=0;i<ARRAYSIZE;i++)
    {
        array[i]=rand()%1000;
        //printf("%d ",array[i]);
    }
  if (find_dist(result,array,ARRAYSIZE,3))
    printf ("\n%d %d\n",result[0],result[1]);
  else
    printf ("No items match requirement\n");
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM