给定一个数组arr []和一个数组Q [] [],它们由{L,R}形式的查询组成,每个查询的任务是在从索引范围[L]中删除数组元素后找到最大数组元素,R] 。如果从给定索引范围中删除元素后数组变为空,则打印0 。
例子:
Input: arr[] = {5, 6, 8, 10, 15}, Q = {{0, 1}, {0, 2}, {1, 4}}
Output:
15
15
5
Explanation:
For the first query {0 1}: Remove array elements in range [0, 1], array modifies to {8, 10, 15}. Hence, the maximum element is 15.
For the second query {0, 2}: Remove array elements in range [0, 2], array modifies to {10, 15}. Hence, the maximum element is 15.
For the third query {1 4}: Remove array elements in range [1, 4], array modfies to {5}. Hence, the maximum element is 5.
Input: arr[] = {8, 12, 14, 10, 13}, Q = {{0, 3}, {0, 4}, {4, 4}}
Output:
13
-1
14
天真的方法:最简单的方法是在删除每个查询中给定范围内的数组元素后遍历数组以找到最大元素。
时间复杂度: O(N * Q)
辅助空间: O(1)
高效方法:为了优化上述方法,我们的想法是使用两个辅助数组:一个将存储前缀最大值(最大元素在[0,i]范围内),另一个数组将存储后缀最大值(最大元素在后缀中)。范围[i,N – 1] )。然后,对于每个查询[L,R] ,答案将是prefixMax [l – 1]和suffixMax [r +1]的最大值。请按照以下步骤解决问题:
- 初始化两个辅助数组:大小为N + 1的prefixMax和suffixMax ,并将prefixMax [0]初始化为arr [0],并将suffixMax [N – 1]初始化为arr [N – 1] 。
- 使用变量i在[1,N – 1]范围内进行迭代,并将prefixMax [i]设置为prefixMax [i – 1]和arr [i]的最大值。
- 使用变量i在[N – 2,0]范围内进行迭代,并将suffixMax [i]设置为suffixMax [i + 1]和arr [i]的最大值。
- 遍历数组Q [] [] ,对于每个查询,请检查以下条件:
- 如果L = 0且R = N – 1 ,则打印0 。
- 否则,如果L = 0 ,则打印后缀Max [R + 1]作为结果。
- 否则,如果R = N – 1 ,则输出prefixMax [L – 1]作为结果。
- 对于所有其他情况,请打印最大的prefixMax [L – 1]和suffixMax [R + 1] 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum element
// after removing elements in range [l, r]
int findMaximum(int arr[], int N, int Q,
int queries[][2])
{
// Store prefix maximum element
int prefix_max[N + 1] = { 0 };
// Store suffix maximum element
int suffix_max[N + 1] = { 0 };
// Prefix max till first index
// is first index itself
prefix_max[0] = arr[0];
// Traverse the array to fill
// prefix max array
for (int i = 1; i < N; i++) {
// Store maximum till index i
prefix_max[i]
= max(prefix_max[i - 1],
arr[i]);
}
// Suffix max till last index
// is last index itself
suffix_max[N - 1] = arr[N - 1];
// Traverse the array to fill
// suffix max array
for (int i = N - 2; i >= 0; i--) {
// Store maximum till index i
suffix_max[i]
= max(suffix_max[i + 1],
arr[i]);
}
// Traverse all queries
for (int i = 0; i < Q; i++) {
// Store the starting and the
// ending index of the query
int l = queries[i][0];
int r = queries[i][1];
// Edge Cases
if (l == 0 && r == (N - 1))
cout << "0\n";
else if (l == 0)
cout << suffix_max[r + 1]
<< "\n";
else if (r == (N - 1))
cout << prefix_max[l - 1]
<< "\n";
// Otherwise
else
cout << max(prefix_max[l - 1],
suffix_max[r + 1])
<< "\n";
}
}
// Driver Code
int main()
{
int arr[] = { 5, 6, 8, 10, 15 };
int N = sizeof(arr) / sizeof(arr[0]);
int queries[][2] = { { 0, 1 }, { 0, 2 }, { 1, 4 } };
int Q = sizeof(queries) / sizeof(queries[0]);
findMaximum(arr, N, Q, queries);
return 0;
}
Java
// Java program for the above approach
class GFG
{
// Function to find the maximum element
// after removing elements in range [l, r]
static void findMaximum(int arr[], int N, int Q,
int queries[][])
{
// Store prefix maximum element
int prefix_max[] = new int[N + 1];
// Store suffix maximum element
int suffix_max[] = new int[N + 1];
// Prefix max till first index
// is first index itself
prefix_max[0] = arr[0];
// Traverse the array to fill
// prefix max array
for (int i = 1; i < N; i++) {
// Store maximum till index i
prefix_max[i]
= Math.max(prefix_max[i - 1],
arr[i]);
}
// Suffix max till last index
// is last index itself
suffix_max[N - 1] = arr[N - 1];
// Traverse the array to fill
// suffix max array
for (int i = N - 2; i >= 0; i--) {
// Store maximum till index i
suffix_max[i]
= Math.max(suffix_max[i + 1],
arr[i]);
}
// Traverse all queries
for (int i = 0; i < Q; i++) {
// Store the starting and the
// ending index of the query
int l = queries[i][0];
int r = queries[i][1];
// Edge Cases
if (l == 0 && r == (N - 1))
System.out.print("0\n");
else if (l == 0)
System.out.print(suffix_max[r + 1]
+ "\n");
else if (r == (N - 1))
System.out.print(prefix_max[l - 1]
+ "\n");
// Otherwise
else
System.out.print(Math.max(prefix_max[l - 1],
suffix_max[r + 1])
+ "\n");
}
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 5, 6, 8, 10, 15 };
int N = arr.length;
int queries[][] = { { 0, 1 }, { 0, 2 }, { 1, 4 } };
int Q = queries.length;
findMaximum(arr, N, Q, queries);
}
}
// This code is contributed by shikhasingrajput
Python3
# Python3 program for the above approach
# Function to find the maximum element
# after removing elements in range [l, r]
def findMaximum(arr, N, Q, queries):
# Store prefix maximum element
prefix_max = [0]*(N + 1)
# Store suffix maximum element
suffix_max = [0]*(N + 1)
# Prefix max till first index
# is first index itself
prefix_max[0] = arr[0]
# Traverse the array to fill
# prefix max array
for i in range(1, N):
# Store maximum till index i
prefix_max[i]= max(prefix_max[i - 1], arr[i])
# Suffix max till last index
# is last index itself
suffix_max[N - 1] = arr[N - 1]
# Traverse the array to fill
# suffix max array
for i in range(N - 2, -1, -1):
# Store maximum till index i
suffix_max[i] = max(suffix_max[i + 1], arr[i])
# Traverse all queries
for i in range(Q):
# Store the starting and the
# ending index of the query
l = queries[i][0]
r = queries[i][1]
# Edge Cases
if (l == 0 and r == (N - 1)):
print("0")
elif (l == 0):
print(suffix_max[r + 1])
elif (r == (N - 1)):
print(prefix_max[l - 1])
# Otherwise
else:
print(max(prefix_max[l - 1], suffix_max[r + 1]))
# Driver Code
if __name__ == '__main__':
arr = [5, 6, 8, 10, 15]
N = len(arr)
queries = [ [ 0, 1 ], [ 0, 2 ], [ 1, 4 ] ]
Q = len(queries)
findMaximum(arr, N, Q, 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 element
// after removing elements in range [l, r]
static void findMaximum(int[] arr, int N, int Q,
int[,] queries)
{
// Store prefix maximum element
int[] prefix_max = new int[N + 1];
// Store suffix maximum element
int[] suffix_max = new int[N + 1];
// Prefix max till first index
// is first index itself
prefix_max[0] = arr[0];
// Traverse the array to fill
// prefix max array
for (int i = 1; i < N; i++)
{
// Store maximum till index i
prefix_max[i]
= Math.Max(prefix_max[i - 1],
arr[i]);
}
// Suffix max till last index
// is last index itself
suffix_max[N - 1] = arr[N - 1];
// Traverse the array to fill
// suffix max array
for (int i = N - 2; i >= 0; i--)
{
// Store maximum till index i
suffix_max[i]
= Math.Max(suffix_max[i + 1],
arr[i]);
}
// Traverse all queries
for (int i = 0; i < Q; i++)
{
// Store the starting and the
// ending index of the query
int l = queries[i, 0];
int r = queries[i, 1];
// Edge Cases
if (l == 0 && r == (N - 1))
Console.Write("0\n");
else if (l == 0)
Console.Write(suffix_max[r + 1]
+ "\n");
else if (r == (N - 1))
Console.Write(prefix_max[l - 1]
+ "\n");
// Otherwise
else
Console.Write(Math.Max(prefix_max[l - 1],
suffix_max[r + 1])
+ "\n");
}
}
// Driver Code
static public void Main ()
{
int[] arr = { 5, 6, 8, 10, 15 };
int N = arr.Length;
int[,] queries = { { 0, 1 }, { 0, 2 }, { 1, 4 } };
int Q = queries.GetLength(0);
findMaximum(arr, N, Q, queries);
}
}
// This code is contributed by sanjoy_62.
15
15
5
时间复杂度: O(N + Q)
辅助空间: O(N)