如何在给定数组的任何子数组(任何大小)中找到最大值(或最小值)?
How to find maximum(or minimum) in any subarray(of any size) in a given array?
我们得到了一个数组和一些查询。每个查询包含两个数字i
和j
。我们需要找到子数组中从索引i
开始到给定数组中的索引j
结束的最大(或最小(元素。
例如。
arr = [2 , 3 , 5, 8 , 4 , 9]
和
query 1: (2 , 4)
与此查询对应的子数组将[5 , 8 , 4]
。因此,最大值将是8
.
注意:查询数约为 10^5,数组中大约有 10^6 个元素。程序执行的时间限制也是 1s .所以,我想需要一个解决方案,每个查询的复杂度为 O(log n( 或更低,其中 n 是数组中元素的数量。
为了详细说明Yeldar的RSQ想法,并假设你只需要找到最大值(否则,也对最小值重复这个结构(: -您已经拥有每个条目的值。 现在将数组分成对,并存储每对的最大值。 (所以在你的例子中,你会得到 3,8,9(。 然后将它们分成对(4 个原始条目(并存储其中的最大值(所以 8,9;奇数一个单独保留(。 重复此操作,直到减少到一对,从而获得整个阵列中的最大值。 因此,您拥有树的多个级别,每个级别对应于一个子数组。
-现在,您可以使用此树更有效地查找每个最大值:如果您需要找到从 i 到 j 的最大值,请找到树中完全包含从 i 到 j 范围的最小子数组。 现在您可以(从树中(看到该子数组的最大值,因此向下跟踪它(因为每个较高级别的子数组由两个较低级别的子数组组成(,直到您得到完全包含在 i 到 j 的范围内或完全不相交的内容。 跟踪时,请跟踪不采用的每条路径的最大值。
如果它完全包含,则您有答案(该范围的最大值(。 如果它完全不相交,那么它不是你的答案(它来自不在范围内的东西(,所以从你没有采取的路径中获取最高最大值并重复该过程(添加任何新的未采取路径(,直到你的最大值最终来自完全包含在范围内的子数组。
您可以尝试通过遍历所有元素来存储初始输入的最大值和最小值,如果 i 和 j 包含上一个输入,则可以使用上一个结果来节省时间。
可以使用STL:max_element
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
std::vector<int> v{2,3,5,8,4,9};
int initial , end;
cin>>initial>>end;
cout <<*(std::max_element(v.begin()+initial,v.begin()+end));
return 0;
}
其他方式仅适用于 C++17
http://coliru.stacked-crooked.com/view?id=3de476681d9e1374
#include <iostream>
#include <algorithm>
#include <experimental/array>
using namespace std;
int main()
{
decltype(auto) v = std::experimental::make_array(2,3,5,8,4,9);
int initial=2,end=4;
cout <<*(std::max_element(v.begin()+initial,v.begin()+end));
return 0;
}
我能想到的最简单的方法是将数组存储为平衡搜索树,该树在每个节点下存储最小值,以便每个索引都映射到其值。
然后你可以按 j 拆分,按 i 拆分(平衡树保持当前节点子树最小值(,并返回根最小值。然后重新连接您获得的(最多(3棵树。
构造是 O(n log n(,查询是 O(log n( [因为拆分和连接是在 O(log n( 中完成的]
counter = i-1
max = MIN_INTEGER
min = MAX_INTEGER
while counter < j:
if arr[counter] > max:
max = arr[counter]
if arr[counter] < min:
min = arr[counter]
counter++
return max,min
编辑:
或者,将其插入到最大堆和最小堆 (O(n(( 中,此后查询都将为 O(1(。
您可以使用C++ STL(这是对先前所述解决方案的修改。我们需要在末尾添加 +1。因为它在 [开始、结束] 范围内采用索引。希望这有帮助。尝试这个问题以更好地理解。https://www.hackerrank.com/challenges/service-lane/problem
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> arr{2,3,5,8,4,9};
int i; // start index
int j; // end index
cin >> i >> j;
cout << *max_element(arr.begin()+i, arr.begin()+j+1);
return 0;
}
- 使用指针从C++中的数组中获取最大值
- 在二维数组中查找最小值和最大值?
- 查找数组中第一个最小值和最后一个最大值元素之间的算术平均值
- CUDA - 将 float3 数组的 (x,y,z) 分量的最小值/最大值分开?
- 查找包含 N 个元素的数组的最小值和最大值
- 有没有一种惯用的方法可以在不存储变换或不必要地重新计算的情况下找到数组变换的最小/最大值?
- C++ 从数组中删除一个最大值和零
- 我无法显示包含整数最大值的索引. 但我可以显示数组中整数的最高值
- 使用数组将最后一个最大值更改为第一个最小值
- 练习循环和使用循环 1 次以及如何获取数组的最大值
- 如何在给定数组的任何子数组(任何大小)中找到最大值(或最小值)?
- C++数组的最大值、最小值、平均值函数
- C ++试图找到数组中每一行的最大值
- 从二维数组中查找最小值和最大值
- 数组的最大值
- 数组函数似乎没有找到最大值
- 未初始化数组中的最小值和最大值
- 堆栈或BSS或DATA段上的数组最大大小
- 数的最大值
- 确定strftime字符数组最大大小的智能方法是什么?