给定一个数组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)
。
方法是否正确?有可能制定线性时间解决方案吗?我尝试使用散列图,但很难找到线性解决方案。
答案 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 中是线性的。
将所有元素放在哈希表中,将每个元素 e 映射到数组 i 中的位置(如果有多个 e ,让你在哈希表中放置的每个条目都覆盖前一个 - 这没关系。)
对于位置 i 的每个元素 e , d = -k, - (k - 1),... 0,1 ,... k ,检查 e + d 是否在哈希表中。如果是这样,您将从哈希表中获得 e + d 的位置,例如 j 。
保留您在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
由于我们搜索最大值,我们将首先通过最大距离进行调查。所以我们有最好的情况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");
}