Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 查找距离数组中某点最远且小于给定数的数_Arrays_Data Structures_Range_Distance - Fatal编程技术网

Arrays 查找距离数组中某点最远且小于给定数的数

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)?事实上,如果数组是静态的,并

给定一个数字列表以及一个索引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)?

事实上,如果数组是静态的,并且您希望对每个
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];
}