如何在给定数组的任何子数组(任何大小)中找到最大值(或最小值)?

How to find maximum(or minimum) in any subarray(of any size) in a given array?

本文关键字:数组 最大值 最小值 任何 任何大      更新时间:2023-10-16

我们得到了一个数组和一些查询。每个查询包含两个数字ij。我们需要找到子数组中从索引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;
}