Arrays 查找距离数组中某点最远且小于给定数的数
给定一个数字列表以及一个索引i和整数k,我希望找到距离索引i处的数字最远(向左)且小于k的数字的索引Arrays 查找距离数组中某点最远且小于给定数的数,arrays,data-structures,range,distance,Arrays,Data Structures,Range,Distance,给定一个数字列表以及一个索引i和整数k,我希望找到距离索引i处的数字最远(向左)且小于k的数字的索引 eg if the array is Index :0 1 2 3 4 5 6 7 ..... Array :3 4 1 5 5 4 3 7 ..... Assuming i = 7 and k = 4 , the answer would be 0 我一直试图用红黑树来实现这一点,但我不能低于O(n)。有没有办法通过使用不同的数据结构将复杂性降低到O(logn)?事实上,如果数组是静态的,并
eg
if the array is
Index :0 1 2 3 4 5 6 7 .....
Array :3 4 1 5 5 4 3 7 .....
Assuming i = 7 and k = 4 , the answer would be 0
我一直试图用红黑树来实现这一点,但我不能低于O(n)。有没有办法通过使用不同的数据结构将复杂性降低到O(logn)?事实上,如果数组是静态的,并且您希望对每个
O(logn)
进行多个查询,那么您不需要那么复杂的数据结构
您实际要求的——“距离索引i处的数字最远(向左)且小于k的数字”——可以转换为“在i
之前小于k的最左边数字”。然后您可以看到如下所示:
- 找到小于K的最左边的数字-说它在位置
j
李>
- 如果
j
,j
是问题的答案
- 否则,没有这样的数字-位置
i
之前的所有条目都大于或等于k
要回答第一个问题,您需要知道的是:对于职位i
,职位0..i
上的最小数字是多少?我们称之为min(i)
。请注意,min
是i
的单调递减函数-如果min(5)=10
,则min(6)=15
,因为min(6)
是0
到6
位置上的最小数字,这必然包括位置0
到5
的最小数字,我们知道是10。(min
构造起来相当简单-如果我们称数组为a
,那么:min(0)=a[0]
,而min(i)=最小值(min(i-1),a[i])
表示i>0
)
有了这些信息,您可以对最左边的索引i
执行二进制搜索,以便min(i)
。然后,通过构造min
,我们知道从0
到i-1
位置上的所有数字都大于或等于k
。因此,i
必须是问题的答案。一种方法是为每个0构建一个数组mp
int minPos = 0;
for (int i = 0; i < n; ++i) {
if (a[i] < a[minPos]) minPos = i;
mp[i] = minPos;
}
int find(int i, int k) {
int start = 0;
int end = i - 1;
if (a[mp[end]] >= k) return -1; // Not found.
if (a[mp[start]] < k) return mp[start]; // The first element is smaller.
// We maintain the invariant that a[mp[start]] is >= k and a[mp[end]] is < k.
while (end - start > 1) {
int mid = (start + end) / 2;
if (a[mp[mid]] < k) {
end = mid;
} else {
start = mid;
}
}
return mp[end];
}