我有一个未排序的数组。我有许多查询,其中我给出了一个范围(表示为两个数组索引),然后必须返回该范围的最大值(即,来自数组的指定切片)。例如:
array[]={23,17,9,45,78,2,4,6,90,1};
query(both inclusive): 2 6
answer: 78
我构建哪种算法或数据结构来快速检索任何范围的最大值。(有很多疑问)
编辑: 我正在使用 C++
我有一个未排序的数组。我有许多查询,其中我给出了一个范围(表示为两个数组索引),然后必须返回该范围的最大值(即,来自数组的指定切片)。例如:
array[]={23,17,9,45,78,2,4,6,90,1};
query(both inclusive): 2 6
answer: 78
我构建哪种算法或数据结构来快速检索任何范围的最大值。(有很多疑问)
编辑: 我正在使用 C++
我认为允许进行一些预处理。这是范围最小查询问题(这里是最大值)。 在 TopCoder 对这个问题进行了很好的回顾。合适的数据结构: Segment tree 和Sqrt-decomposition:
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N int(3e4)
using namespace std;
int act[N], len, sz, res[N];
int answer(int l, int r) {
int ret = -1, i;
for (i = l; i % sz && i <= r; i++)
ret = max(ret, act[i]);
for (; i + sz <= r + 1; i += sz)
ret = max(ret, res[i / sz]);
for (; i <= r; i++)
ret = max(ret, act[i]);
return ret;
}
int main() {
int i, m;
cin >> m;
for (i = 0; ; i++) {
cin >> act[i];
if (act[i] == -1)
break;
}
len = i;
for (sz = 1; sz * sz < len; sz++);
for (int j = i + 1; j < sz * sz; j++)
act[j] = -1;
for (int i = 0; i < sz * sz; i++)
res[i / sz] = max(res[i / sz], act[i]);
for (int i = 0; i + m <= len; i++)
cout << answer(i, i + m - 1) << endl;
return 0;
}
合并排序 n 获取范围的最后一个索引值,我将最大。
数组[]={23,17,9,45,78,2,4,6,90,1}; 查询(含):2 6
合并排序返回第 6 个索引 var (index = 1 .. n)
答案:78
假设这是你的数组array[]={23,17,9,45,78,2,4,6,90,1};
如果您的数组不是那么大,我会为您提供预处理数组并获得另一个这样的数组:
{0,0} = 23; //between arr[0] and arr[0]
{0,1} = 23;
{0,2} = 23;
{0,3} = 45;
{9,9} = 1;
所以你的新阵列将是newArr = {23,23,23,45,....., 1}
您可以在 O(1) 中找到搜索,例如,newArr[4*array.length+5)-1];
总共 4-5 之间的最大值是,对于 n 个查询,您将有 O(n)。
空间是如果你有10000(10^4) integer,那么你的newArr = 10^8 * 4B = 400MB,所以如果你有超过10000 int,那么这不起作用
编辑:我想到了一些东西,但它与MBo提到的 Topcoder中的算法相同。