[英]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)
+ rangeQuery
, O(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是线性的。
将所有元素放在一个哈希表中,将每个元素e映射到它在数组i中的位置(如果有多个e ,让你在哈希表中放置的每个条目都覆盖前一个 - 这没关系)。
对于位置i处的每个元素e ,以及d = -k, - (k-1),... 0,1,... k ,检查e + d是否在哈希表中。 如果是这样,你就可以从哈希表中获得e + d的位置,比如j 。
保留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
由于我们搜索最大值,我们将首先通过最大距离进行调查。 所以我们有最好的情况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.