最大范围长度,使得 A[i] 在给定范围内为来自 [1, N] 的所有 i 的最大值
给定一个由N个不同整数组成的数组arr[] 。对于每个i (0 ≤ i < n),找到一个范围[l, r]使得A[i] = max(A[l], A[l+1], ..., A[r])并且l ≤ i ≤ r并且rl最大化。
例子:
Input: arr[] = {1, 3, 2}
Output: {0 0}, {0 2}, {2 2}
Explanation: For i=0, 1 is maximum in range [0, 0] only. For i=1, 3 is maximum in range [0, 2] and for i = 2, 2 is maximum in range [2, 2] only.
Input: arr[] = {1, 2}
Output: {0, 0}, {0, 1}
朴素方法:解决问题的最简单方法是对每个i ,使用变量r在范围[i+1, N-1]中迭代,并使用变量l在范围[i-1, 0]中迭代并终止分别在arr[l] > arr[i]和arr[r]>arr[i]时循环。答案将是[l, r] 。
时间复杂度: O(N×N)
辅助空间: O(1)
高效方法:上述方法可以通过使用堆栈数据结构进一步优化。请按照以下步骤解决问题:
- 初始化两个向量,比如left和right ,它们将分别存储每个i的左索引和右索引。
- 初始化一堆对,比如s 。
- 将 INT_MAX和-1作为一对插入堆栈中。
- 使用变量i在[0, N-1]范围内迭代并执行以下步骤:
- 在s.top().first
时,从堆栈中弹出顶部元素。 - 将left[i]的值修改为s.top().second 。
- 将{arr[i], i}压入堆栈。
- 在s.top().first
- 现在从堆栈中删除所有元素。
- 将 INT_MAX和N成对插入堆栈。
- 使用变量i在[N-1, 0]范围内迭代并执行以下步骤:
- 在s.top().first
时,从堆栈中弹出顶部元素。 - 将right[i]的值修改为s.top().second 。
- 将{arr[i], i}压入堆栈。
- 在s.top().first
- 使用变量i在[0, N-1]范围内迭代并打印left[i] +1 , right[i] -1作为第 i 个元素的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find maximum range for
// each i such that arr[i] is max in range
void MaxRange(vector A, int n)
{
// Vector to store the left and right index
// for each i such that left[i]>arr[i]
// and right[i] > arr[i]
vector left(n), right(n);
stack > s;
s.push({ INT_MAX, -1 });
// Traverse the array
for (int i = 0; i < n; i++) {
// While s.top().first= 0; i--) {
// While s.top().first arr{ 1, 3, 2 };
int n = arr.size();
// Function Call
MaxRange(arr, n);
return 0;
}
Java
//Java program for above approach
import java.awt.*;
import java.util.*;
class GFG{
static class pair{
T first;
V second;
}
// Function to find maximum range for
// each i such that arr[i] is max in range
static void MaxRange(ArrayList A, int n)
{
// Vector to store the left and right index
// for each i such that left[i]>arr[i]
// and right[i] > arr[i]
int[] left = new int[n];
int[] right = new int[n];
Stack> s = new Stack<>();
pair x = new pair<>();
x.first =Integer.MAX_VALUE;
x.second = -1;
s.push(x);
// Traverse the array
for (int i = 0; i < n; i++)
{
// While s.top().first y = new pair<>();
y.first = A.get(i);
y.second = i;
s.push(y);
}
// Clear the stack
while (!s.empty())
s.pop();
pair k = new pair<>();
k.first =Integer.MAX_VALUE;
k.second = n;
s.push(k);
// Traverse the array to find
// right[i] for each i
for (int i = n - 1; i >= 0; i--)
{
// While s.top().first y = new pair<>();
y.first = A.get(i);
y.second = i;
s.push(y);
}
// Print the value range for each i
for (int i = 0; i < n; i++) {
System.out.print(left[i]+1);
System.out.print(" ");
System.out.println(right[i]-1);
}
}
// Driver Code
public static void main(String[] args)
{
// Given Input
ArrayList arr = new ArrayList<>();
arr.add(1);
arr.add(3);
arr.add(2);
int n = arr.size();
// Function Call
MaxRange(arr, n);
}
}
// This code is contributed by hritikrommie.
Python3
# Python 3 program for the above approach
import sys
# Function to find maximum range for
# each i such that arr[i] is max in range
def MaxRange(A, n):
# Vector to store the left and right index
# for each i such that left[i]>arr[i]
# and right[i] > arr[i]
left = [0] * n
right = [0] * n
s = []
s.append((sys.maxsize, -1))
# Traverse the array
for i in range(n):
# While s.top().first
C#
// C# program for the above approach.
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
// Function to find maximum range for
// each i such that arr[i] is max in range
static void MaxRange(List A, int n)
{
// Vector to store the left and right index
// for each i such that left[i]>arr[i]
// and right[i] > arr[i]
int[] left = new int[n];
int[] right = new int[n];
Stack s = new Stack();
s.Push(new Tuple(Int32.MaxValue, -1));
// Traverse the array
for (int i = 0; i < n; i++)
{
// While s.top().first)s.Peek()).Item1 < A[i])
s.Pop();
// Modify left[i]
left[i] = ((Tuple)s.Peek()).Item2;
s.Push(new Tuple(A[i], i));
}
// Clear the stack
while (s.Count > 0)
s.Pop();
s.Push(new Tuple(Int32.MaxValue, n));
// Traverse the array to find
// right[i] for each i
for (int i = n - 1; i >= 0; i--) {
// While s.top().first)s.Peek()).Item1 < A[i])
s.Pop();
// Modify right[i]
right[i] = ((Tuple)s.Peek()).Item2;
s.Push(new Tuple(A[i], i));
}
// Print the value range for each i
for (int i = 0; i < n; i++) {
Console.WriteLine((left[i] + 1) + " " + (right[i] - 1));
}
}
static void Main ()
{
List arr = new List();
// adding elements in firstlist
arr.Add(1);
arr.Add(3);
arr.Add(2);
int n = arr.Count;
// Function Call
MaxRange(arr, n);
}
}
// This code is contributed by suresh07.
Javascript
输出:
0 0
0 2
2 2
时间复杂度: O(N)
辅助空间: O(N)