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

时间:2016-09-21 04:17:38

标签: arrays algorithm

给定一个数组arr,找到最大abs(i-j),使得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(n log n) + O(log n)rangeQuery的每个元素,排序+的复杂度为O(log n)。总时间复杂度为O(nlogn + n*2*logn),渐近O(nlogn)

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

3 个答案:

答案 0 :(得分:1)

我想出了这个:

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²)。如果存在线性算法,我感兴趣

答案 1 :(得分:1)

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

对于元素都是整数的情况,您可以在Θ(n k)预期时间内完成。如果 k = o(log(n))this is a saving。如果 k 是常量,则在 n 中是线性的。

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

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

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

答案 2 :(得分:0)

似乎有点强迫“线性”的定义。 我会以不同的方式接近。我们可以注意到函数距离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");
 }