给定一个由n个整数组成的数组arr []和一个由[L,R]形式的查询组成的数组Q [] [ ]。 ,每个查询的任务是查找数组中的最大和最小数组元素,但不包括给定范围内的元素。
例子:
Input: arr[] = {2, 3, 1, 8, 3, 5, 7, 4}, Q[][] = {{4, 6}, {0, 4}, {3, 7}, {2, 5}}
Output:
8 1
7 4
3 1
7 2
Explanation:
Query 1: max(arr[0, 1, …, 3], arr[7]) = 8 and min(arr[0, 1, …, 3], arr[7]) = 1
Query 2: max(arr[5, 6, …, 7]) = 7 and min(arr[5, 6, …, 7]) = 4
Query 3: max(arr[0, 1, …, 2]) =3 and min(arr[0, 1, …, 2]) = 1
Query 4: max(arr[0, 1], arr[6, …, 7]) =7 and min(arr[0, 1], arr[6, …, 7]) = 2
Input: arr[] = {3, 2, 1, 4, 5}, Q[][] = {{1, 2}, {2, 4}}
Output:
5 3
3 2
天真的方法:解决问题的最简单方法是遍历每个查询的数组,并找到索引[L,R]范围之外的最大和最小元素。
时间复杂度: O(N 2 )
辅助空间: O(1)
高效方法:通过将数组划分为多个子范围,将问题划分为多个子任务,并找到从arr [0]到arr [L – 1]以及从arr [r + 1]到arr [N – 1]的最大值和最小值并将它们分别存储在前缀和后缀数组中。现在,通过比较前缀和后缀数组,找到给定范围的最大值和最小值。
请按照以下步骤操作:
- 通过将当前索引处的值与前一个索引的最大值和最小值进行比较,遍历数组并保持2D前缀数组中每个索引遇到的最大和最小元素。
- 现在,迭代由所述值与下一个索引的最大值和最小值的当前索引处比较在对2D后缀数组索引反向和保持的最大和最小值的数组。
- 现在,对于每个查询,请执行以下步骤:
- 如果L = 0且R = N – 1 ,则排除范围后没有元素剩余。
- 否则,如果L = 0 ,则最大值和最小值将出现在arr [R + 1]至arr [N – 1]之间。
- 否则,如果R = N – 1 ,则最大值和最小值将出现在arr [0]至arr [L – 1]之间。
- 否则,在arr [0]到arr [L – 1]和arr [R +1]到arr [N – 1]范围内找到最大值和最小值。
- 打印此查询的最大值和最小值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum and
// minimum array elements up to the i-th index
void prefixArr(int arr[], int prefix[][2], int N)
{
// Traverse the array
for (int i = 0; i < N; i++) {
if (i == 0) {
prefix[i][0] = arr[i];
prefix[i][1] = arr[i];
}
else {
// Compare current value with maximum
// and minimum values up to previous index
prefix[i][0] = max(prefix[i - 1][0], arr[i]);
prefix[i][1] = min(prefix[i - 1][1], arr[i]);
}
}
}
// Function to find the maximum and
// minimum array elements from i-th index
void suffixArr(int arr[], int suffix[][2], int N)
{
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--) {
if (i == N - 1) {
suffix[i][0] = arr[i];
suffix[i][1] = arr[i];
}
else {
// Compare current value with maximum
// and minimum values in the next index
suffix[i][0] = max(suffix[i + 1][0], arr[i]);
suffix[i][1] = min(suffix[i + 1][1], arr[i]);
}
}
}
// Function to find the maximum and
// minimum array elements for each query
void maxAndmin(int prefix[][2],
int suffix[][2],
int N, int L, int R)
{
int maximum, minimum;
// If no index remains after
// excluding the elements
// in a given range
if (L == 0 && R == N - 1) {
cout << "No maximum and minimum value" << endl;
return;
}
// Find maximum and minimum from
// from the range [R + 1, N - 1]
else if (L == 0) {
maximum = suffix[R + 1][0];
minimum = suffix[R + 1][1];
}
// Find maximum and minimum from
// from the range [0, N - 1]
else if (R == N - 1) {
maximum = prefix[L - 1][0];
minimum = prefix[R - 1][1];
}
// Find maximum and minimum values from the
// ranges [0, L - 1] and [R + 1, N - 1]
else {
maximum = max(prefix[L - 1][0],
suffix[R + 1][0]);
minimum = min(prefix[L - 1][1],
suffix[R + 1][1]);
}
// Print the maximum and minimum value
cout << maximum << " " << minimum << endl;
}
// Function to perform queries to find the
// minimum and maximum array elements excluding
// elements from a given range
void MinMaxQueries(int a[], int Q[][])
{
// Size of the array
int N = sizeof(arr) / sizeof(arr[0]);
// Size of query array
int q = sizeof(queries) / sizeof(queries[0]);
// prefix[i][0]: Stores the maximum
// prefix[i][1]: Stores the minimum value
int prefix[N][2];
// suffix[i][0]: Stores the maximum
// suffix[i][1]: Stores the minimum value
int suffix[N][2];
// Function calls to store
// maximum and minimum values
// for respective ranges
prefixArr(arr, prefix, N);
suffixArr(arr, suffix, N);
for (int i = 0; i < q; i++) {
int L = queries[i][0];
int R = queries[i][1];
maxAndmin(prefix, suffix, N, L, R);
}
}
// Driver Code
int main()
{
// Given array
int arr[] = { 2, 3, 1, 8, 3, 5, 7, 4 };
int queries[][2]
= { { 4, 6 }, { 0, 4 }, { 3, 7 }, { 2, 5 } };
MinMaxQueries(arr, Q);
return 0;
}
Java
// Java program for the above approach
public class GFG
{
// Function to find the maximum and
// minimum array elements up to the i-th index
static void prefixArr(int arr[], int prefix[][], int N)
{
// Traverse the array
for (int i = 0; i < N; i++)
{
if (i == 0)
{
prefix[i][0] = arr[i];
prefix[i][1] = arr[i];
}
else
{
// Compare current value with maximum
// and minimum values up to previous index
prefix[i][0] = Math.max(prefix[i - 1][0], arr[i]);
prefix[i][1] = Math.min(prefix[i - 1][1], arr[i]);
}
}
}
// Function to find the maximum and
// minimum array elements from i-th index
static void suffixArr(int arr[], int suffix[][], int N)
{
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--)
{
if (i == N - 1)
{
suffix[i][0] = arr[i];
suffix[i][1] = arr[i];
}
else
{
// Compare current value with maximum
// and minimum values in the next index
suffix[i][0] = Math.max(suffix[i + 1][0], arr[i]);
suffix[i][1] = Math.min(suffix[i + 1][1], arr[i]);
}
}
}
// Function to find the maximum and
// minimum array elements for each query
static void maxAndmin(int prefix[][],
int suffix[][],
int N, int L, int R)
{
int maximum, minimum;
// If no index remains after
// excluding the elements
// in a given range
if (L == 0 && R == N - 1)
{
System.out.println("No maximum and minimum value");
return;
}
// Find maximum and minimum from
// from the range [R + 1, N - 1]
else if (L == 0)
{
maximum = suffix[R + 1][0];
minimum = suffix[R + 1][1];
}
// Find maximum and minimum from
// from the range [0, N - 1]
else if (R == N - 1)
{
maximum = prefix[L - 1][0];
minimum = prefix[R - 1][1];
}
// Find maximum and minimum values from the
// ranges [0, L - 1] and [R + 1, N - 1]
else
{
maximum = Math.max(prefix[L - 1][0],
suffix[R + 1][0]);
minimum = Math.min(prefix[L - 1][1],
suffix[R + 1][1]);
}
// Print the maximum and minimum value
System.out.println(maximum + " " + minimum);
}
// Function to perform queries to find the
// minimum and maximum array elements excluding
// elements from a given range
static void MinMaxQueries(int a[], int Q[][])
{
// Size of the array
int N = a.length;
// Size of query array
int q = Q.length;
// prefix[i][0]: Stores the maximum
// prefix[i][1]: Stores the minimum value
int prefix[][] = new int[N][2];
// suffix[i][0]: Stores the maximum
// suffix[i][1]: Stores the minimum value
int suffix[][] = new int[N][2];
// Function calls to store
// maximum and minimum values
// for respective ranges
prefixArr(a, prefix, N);
suffixArr(a, suffix, N);
for (int i = 0; i < q; i++)
{
int L = Q[i][0];
int R = Q[i][1];
maxAndmin(prefix, suffix, N, L, R);
}
}
// Driver Code
public static void main (String[] args)
{
// Given array
int arr[] = { 2, 3, 1, 8, 3, 5, 7, 4 };
int queries[][]
= { { 4, 6 }, { 0, 4 }, { 3, 7 }, { 2, 5 } };
MinMaxQueries(arr, queries);
}
}
// This code is contributed by AnkThon
Python3
# Python3 program for the above approach
# Function to find the maximum and
# minimum array elements up to the i-th index
def prefixArr(arr, prefix, N):
# Traverse the array
for i in range(N):
if (i == 0):
prefix[i][0] = arr[i]
prefix[i][1] = arr[i]
else:
# Compare current value with maximum
# and minimum values up to previous index
prefix[i][0] = max(prefix[i - 1][0], arr[i])
prefix[i][1] = min(prefix[i - 1][1], arr[i])
return prefix
# Function to find the maximum and
# minimum array elements from i-th index
def suffixArr(arr, suffix, N):
# Traverse the array in reverse
for i in range(N - 1, -1, -1):
if (i == N - 1):
suffix[i][0] = arr[i]
suffix[i][1] = arr[i]
else:
# Compare current value with maximum
# and minimum values in the next index
suffix[i][0] = max(suffix[i + 1][0], arr[i])
suffix[i][1] = min(suffix[i + 1][1], arr[i])
return suffix
# Function to find the maximum and
# minimum array elements for each query
def maxAndmin(prefix, suffix, N, L, R):
maximum, minimum = 0, 0
# If no index remains after
# excluding the elements
# in a given range
if (L == 0 and R == N - 1):
print("No maximum and minimum value")
return
# Find maximum and minimum from
# from the range [R + 1, N - 1]
elif (L == 0):
maximum = suffix[R + 1][0]
minimum = suffix[R + 1][1]
# Find maximum and minimum from
# from the range [0, N - 1]
elif (R == N - 1):
maximum = prefix[L - 1][0]
minimum = prefix[R - 1][1]
# Find maximum and minimum values from the
# ranges [0, L - 1] and [R + 1, N - 1]
else:
maximum = max(prefix[L - 1][0], suffix[R + 1][0])
minimum = min(prefix[L - 1][1], suffix[R + 1][1])
# Prthe maximum and minimum value
print(maximum, minimum)
# Function to perform queries to find the
# minimum and maximum array elements excluding
# elements from a given range
def MinMaxQueries(a, queries):
# Size of the array
N = len(arr)
# Size of query array
q = len(queries)
# prefix[i][0]: Stores the maximum
# prefix[i][1]: Stores the minimum value
prefix = [ [ 0 for i in range(2)] for i in range(N)]
# suffix[i][0]: Stores the maximum
# suffix[i][1]: Stores the minimum value
suffix = [ [ 0 for i in range(2)] for i in range(N)]
# Function calls to store
# maximum and minimum values
# for respective ranges
prefix = prefixArr(arr, prefix, N)
suffix = suffixArr(arr, suffix, N)
for i in range(q):
L = queries[i][0]
R = queries[i][1]
maxAndmin(prefix, suffix, N, L, R)
# Driver Code
if __name__ == '__main__':
# Given array
arr = [ 2, 3, 1, 8, 3, 5, 7, 4 ]
queries = [ [ 4, 6 ], [ 0, 4 ], [ 3, 7 ], [ 2, 5 ] ]
MinMaxQueries(arr, queries)
# This code is contributed by mohit kumar 29.
C#
// C# program for the above approach
using System;
public class GFG
{
// Function to find the maximum and
// minimum array elements up to the i-th index
static void prefixArr(int[] arr, int[,] prefix, int N)
{
// Traverse the array
for (int i = 0; i < N; i++)
{
if (i == 0)
{
prefix[i, 0] = arr[i];
prefix[i, 1] = arr[i];
}
else
{
// Compare current value with maximum
// and minimum values up to previous index
prefix[i, 0] = Math.Max(prefix[i - 1, 0], arr[i]);
prefix[i, 1] = Math.Min(prefix[i - 1, 1], arr[i]);
}
}
}
// Function to find the maximum and
// minimum array elements from i-th index
static void suffixArr(int[] arr, int[,] suffix, int N)
{
// Traverse the array in reverse
for (int i = N - 1; i >= 0; i--)
{
if (i == N - 1)
{
suffix[i, 0] = arr[i];
suffix[i, 1] = arr[i];
}
else
{
// Compare current value with maximum
// and minimum values in the next index
suffix[i, 0] = Math.Max(suffix[i + 1, 0], arr[i]);
suffix[i, 1] = Math.Min(suffix[i + 1, 1], arr[i]);
}
}
}
// Function to find the maximum and
// minimum array elements for each query
static void maxAndmin(int[,] prefix,
int[,] suffix,
int N, int L, int R)
{
int maximum, minimum;
// If no index remains after
// excluding the elements
// in a given range
if (L == 0 && R == N - 1)
{
Console.WriteLine("No maximum and minimum value");
return;
}
// Find maximum and minimum from
// from the range [R + 1, N - 1]
else if (L == 0)
{
maximum = suffix[R + 1, 0];
minimum = suffix[R + 1, 1];
}
// Find maximum and minimum from
// from the range [0, N - 1]
else if (R == N - 1)
{
maximum = prefix[L - 1, 0];
minimum = prefix[R - 1, 1];
}
// Find maximum and minimum values from the
// ranges [0, L - 1] and [R + 1, N - 1]
else
{
maximum = Math.Max(prefix[L - 1, 0],
suffix[R + 1, 0]);
minimum = Math.Min(prefix[L - 1, 1],
suffix[R + 1, 1]);
}
// Print the maximum and minimum value
Console.WriteLine(maximum + " " + minimum);
}
// Function to perform queries to find the
// minimum and maximum array elements excluding
// elements from a given range
static void MinMaxQueries(int[] a, int[,] Q)
{
// Size of the array
int N = a.GetLength(0);
// Size of query array
int q = Q.GetLength(0);
// prefix[i][0]: Stores the maximum
// prefix[i][1]: Stores the minimum value
int[,] prefix = new int[N, 2];
// suffix[i][0]: Stores the maximum
// suffix[i][1]: Stores the minimum value
int[,] suffix = new int[N, 2];
// Function calls to store
// maximum and minimum values
// for respective ranges
prefixArr(a, prefix, N);
suffixArr(a, suffix, N);
for (int i = 0; i < q; i++)
{
int L = Q[i, 0];
int R = Q[i, 1];
maxAndmin(prefix, suffix, N, L, R);
}
}
// Driver Code
static public void Main ()
{
// Given array
int[] arr = { 2, 3, 1, 8, 3, 5, 7, 4 };
int[,] queries = { { 4, 6 }, { 0, 4 },
{ 3, 7 }, { 2, 5 } };
MinMaxQueries(arr, queries);
}
}
// This code is contributed by sanjoy_62.
8 1
7 4
3 1
7 2
时间复杂度: O(N)
辅助空间: O(N)