给定一个由n个整数和q个查询组成的数组,在给定索引元素的右边打印下一个更大的元素数。
例子:
Input: a[] = {3, 4, 2, 7, 5, 8, 10, 6}
q = 2
index = 0,
index = 5
Output: 6
1
Explanation:
The next greater elements
to the right of 3(index 0) are 4,7,5,8,10,6.
The next greater elements to the right
of 8(index 5) are 10.
天真的方法是对从索引到结尾的每个查询进行迭代,并找出右边的下一个更大元素的数量。当我们运行两个嵌套循环时,这将不够高效
时间复杂度: O(N)回答查询。
辅助空间: O(1)
更好的方法是存储每个元素的下一个更大的索引,并对从索引迭代的每个查询运行一个循环,并将递增的计数器保持为j = next [i]。这将避免检查所有元素,并将直接跳到每个元素的下一个更大的元素。但这在像1 2 3 4 5 6这样的情况下效率不够高,在此情况下,下一个更大的元素依次增加,最终导致每个查询取O(n)。
时间复杂度: O(N)回答查询。
辅助空间:下一个更大的元素为O(N)。
一种有效的方法是在next []数组中使用下一个更大的元素来存储下一个更大的元素索引。然后创建一个从n-2开始的dp []数组,因为第n-1个索引的右边没有元素,并且dp [n-1] =0。从后向遍历时,我们使用动态编程来计算元素数右边,我们将备忘录用作dp [next [i]],它为我们提供了当前元素的下一个更大元素右边的数字计数,因此我们向其添加1。如果next [i] =-1,那么我们右边没有任何元素,因此dp [i] = 0。 dp [index]存储右边的下一个更大元素的数量计数。
下面是上述方法的实现。
C++
#include
using namespace std;
// array to store the next greater element index
void fillNext(int next[], int a[], int n)
{
// use of stl stack in c++
stack s;
// push the 0th index to the stack
s.push(0);
// traverse in the loop from 1-nth index
for (int i = 1; i < n; i++) {
// iterate till loop is empty
while (!s.empty()) {
// get the topmost index in the stack
int cur = s.top();
// if the current element is greater
// then the top index-th element, then
// this will be the next greatest index
// of the top index-th element
if (a[cur] < a[i]) {
// initialize the cur index position's
// next greatest as index
next[cur] = i;
// pop the cur index as its greater
// element has been found
s.pop();
}
// if not greater then break
else
break;
}
// push the i index so that its next greatest
// can be found
s.push(i);
}
// iterate for all other index left inside stack
while (!s.empty()) {
int cur = s.top();
// mark it as -1 as no element in greater
// then it in right
next[cur] = -1;
s.pop();
}
}
// Function to count the number of
// next greater numbers to the right
void count(int a[], int dp[], int n)
{
// initializes the next array as 0
int next[n];
memset(next, 0, sizeof(next));
// calls the function to pre-calculate
// the next greatest element indexes
fillNext(next, a, n);
for (int i = n - 2; i >= 0; i--) {
// if the i-th element has no next
// greater element to right
if (next[i] == -1)
dp[i] = 0;
// Count of next greater numbers to right.
else
dp[i] = 1 + dp[next[i]];
}
}
// answers all queries in O(1)
int answerQuery(int dp[], int index)
{
// returns the number of next greater
// elements to the right.
return dp[index];
}
// driver program to test the above function
int main()
{
int a[] = { 3, 4, 2, 7, 5, 8, 10, 6 };
int n = sizeof(a) / sizeof(a[0]);
int dp[n];
// calls the function to count the number
// of greater elements to the right for
// every element.
count(a, dp, n);
// query 1 answered
cout << answerQuery(dp, 3) << endl;
// query 2 answered
cout << answerQuery(dp, 6) << endl;
// query 3 answered
cout << answerQuery(dp, 1) << endl;
return 0;
}
Java
// Java program to print number of NGEs to the right
import java.util.*;
class GFG
{
// array to store the next greater element index
static void fillNext(int next[], int a[], int n)
{
// Use stack
Stack s = new Stack();
// push the 0th index to the stack
s.push(0);
// traverse in the loop from 1-nth index
for (int i = 1; i < n; i++)
{
// iterate till loop is empty
while (s.size() > 0)
{
// get the topmost index in the stack
int cur = s.peek();
// if the current element is greater
// then the top index-th element, then
// this will be the next greatest index
// of the top index-th element
if (a[cur] < a[i])
{
// initialize the cur index position's
// next greatest as index
next[cur] = i;
// pop the cur index as its greater
// element has been found
s.pop();
}
// if not greater then break
else
break;
}
// push the i index so that its next greatest
// can be found
s.push(i);
}
// iterate for all other index left inside stack
while (s.size() > 0)
{
int cur = s.peek();
// mark it as -1 as no element in greater
// then it in right
next[cur] = -1;
s.pop();
}
}
// function to count the number of
// next greater numbers to the right
static void count(int a[], int dp[], int n)
{
// initializes the next array as 0
int next[] = new int[n];
for(int i = 0; i < n; i++)
next[i] = 0;
// calls the function to pre-calculate
// the next greatest element indexes
fillNext(next, a, n);
for (int i = n - 2; i >= 0; i--)
{
// if the i-th element has no next
// greater element to right
if (next[i] == -1)
dp[i] = 0;
// Count of next greater numbers to right.
else
dp[i] = 1 + dp[next[i]];
}
}
// answers all queries in O(1)
static int answerQuery(int dp[], int index)
{
// returns the number of next greater
// elements to the right.
return dp[index];
}
// driver code
public static void main(String args[])
{
int a[] = { 3, 4, 2, 7, 5, 8, 10, 6 };
int n = a.length;
int dp[] = new int[n];
// calls the function to count the number
// of greater elements to the right for
// every element.
count(a, dp, n);
// query 1 answered
System.out.println(answerQuery(dp, 3));
// query 2 answered
System.out.println( answerQuery(dp, 6));
// query 3 answered
System.out.println( answerQuery(dp, 1) );
}
}
// This code is contributed by Arnab Kundu
C#
// C# program to print number of
// NGEs to the right
using System;
using System.Collections;
class GFG
{
// array to store the next greater element index
static void fillNext(int []next, int []a, int n)
{
// Use stack
Stack s = new Stack();
// Push the 0th index to the stack
s.Push(0);
// traverse in the loop from 1-nth index
for (int i = 1; i < n; i++)
{
// iterate till loop is empty
while (s.Count > 0)
{
// get the topmost index in the stack
int cur = (int)s.Peek();
// if the current element is greater
// then the top index-th element, then
// this will be the next greatest index
// of the top index-th element
if (a[cur] < a[i])
{
// initialize the cur index position's
// next greatest as index
next[cur] = i;
// Pop the cur index as its greater
// element has been found
s.Pop();
}
// if not greater then break
else
break;
}
// Push the i index so that its next
// greatest can be found
s.Push(i);
}
// iterate for all other index
// left inside stack
while (s.Count > 0)
{
int cur =(int) s.Peek();
// mark it as -1 as no element in
// greater then it in right
next[cur] = -1;
s.Pop();
}
}
// function to count the number of
// next greater numbers to the right
static void count(int []a, int []dp, int n)
{
// initializes the next array as 0
int []next = new int[n];
for(int i = 0; i < n; i++)
next[i] = 0;
// calls the function to pre-calculate
// the next greatest element indexes
fillNext(next, a, n);
for (int i = n - 2; i >= 0; i--)
{
// if the i-th element has no next
// greater element to right
if (next[i] == -1)
dp[i] = 0;
// Count of next greater numbers to right.
else
dp[i] = 1 + dp[next[i]];
}
}
// answers all queries in O(1)
static int answerQuery(int []dp, int index)
{
// returns the number of next greater
// elements to the right.
return dp[index];
}
// Driver code
public static void Main(String []args)
{
int []a = { 3, 4, 2, 7, 5, 8, 10, 6 };
int n = a.Length;
int []dp = new int[n];
// calls the function to count the number
// of greater elements to the right for
// every element.
count(a, dp, n);
// query 1 answered
Console.WriteLine(answerQuery(dp, 3));
// query 2 answered
Console.WriteLine( answerQuery(dp, 6));
// query 3 answered
Console.WriteLine( answerQuery(dp, 1));
}
}
// This code is contributed by Arnab Kundu
C++
#include
using namespace std;
vector no_NGN(int arr[], int n)
{
vector nxt;
// use of stl stack in c++
stack s;
nxt.push_back(0);
// push the (n-1)th index to the stack
s.push(n - 1);
// traverse in reverse order
for (int i = n - 2; i >= 0; i--) {
while (!s.empty() && arr[i] >= arr[s.top()])
s.pop();
// if no element is greater than arr[i] the
// number of NGEs to right is 0
if (s.empty())
nxt.push_back(0);
else
// number of NGEs to right of arr[i] is
// one greater than the number of NGEs to right
// of higher number to its right
nxt.push_back(nxt[n - s.top() - 1] + 1);
s.push(i);
}
// reverse again because values are in reverse order
reverse(nxt.begin(), nxt.end());
// returns the vector of number of next
// greater elements to the right of each index.
return nxt;
}
int main()
{
int n = 8;
int arr[] = { 3, 4, 2, 7, 5, 8, 10, 6 };
vector nxt = no_NGN(arr, n);
// query 1 answered
cout << nxt[3] << endl;
// query 2 answered
cout << nxt[6] << endl;
// query 3 answered
cout << nxt[1] << endl;
return 0;
}
Java
import java.util.*;
class GFG{
static Vector no_NGN(int arr[], int n)
{
Vector nxt = new Vector<>();
// use of stl stack in Java
Stack s = new Stack<>();
nxt.add(0);
// push the (n-1)th index to the stack
s.add(n - 1);
// traverse in reverse order
for (int i = n - 2; i >= 0; i--)
{
while (!s.isEmpty() && arr[i] >= arr[s.peek()])
s.pop();
// if no element is greater than arr[i] the
// number of NGEs to right is 0
if (s.isEmpty())
nxt.add(0);
else
// number of NGEs to right of arr[i] is
// one greater than the number of NGEs to right
// of higher number to its right
nxt.add(nxt.get(n - s.peek() - 1 ) + 1);
s.add(i);
}
// reverse again because values are in reverse order
Collections.reverse(nxt);
// returns the vector of number of next
// greater elements to the right of each index.
return nxt;
}
// Driver code
public static void main(String[] args)
{
int n = 8;
int arr[] = { 3, 4, 2, 7, 5, 8, 10, 6 };
Vector nxt = no_NGN(arr, n);
// query 1 answered
System.out.print(nxt.get(3) +"\n");
// query 2 answered
System.out.print(nxt.get(6) +"\n");
// query 3 answered
System.out.print(nxt.get(1) +"\n");
}
}
// This code is contributed by Rajput-Ji
C#
using System;
using System.Collections.Generic;
public class GFG{
static List no_NGN(int []arr, int n)
{
List nxt = new List();
// use of stl stack in Java
Stack s = new Stack();
nxt.Add(0);
// push the (n-1)th index to the stack
s.Push(n - 1);
// traverse in reverse order
for (int i = n - 2; i >= 0; i--)
{
while (s.Count!=0 && arr[i] >= arr[s.Peek()])
s.Pop();
// if no element is greater than arr[i] the
// number of NGEs to right is 0
if (s.Count == 0)
nxt.Add(0);
else
// number of NGEs to right of arr[i] is
// one greater than the number of NGEs to right
// of higher number to its right
nxt.Add(nxt[n - s.Peek() - 1 ] + 1);
s.Push(i);
}
// reverse again because values are in reverse order
nxt.Reverse();
// returns the vector of number of next
// greater elements to the right of each index.
return nxt;
}
// Driver code
public static void Main(String[] args)
{
int n = 8;
int []arr = { 3, 4, 2, 7, 5, 8, 10, 6 };
List nxt = no_NGN(arr, n);
// query 1 answered
Console.Write(nxt[3] +"\n");
// query 2 answered
Console.Write(nxt[6] +"\n");
// query 3 answered
Console.Write(nxt[1] +"\n");
}
}
// This code iscontributed by aashish1995
输出
2
0
3
时间复杂度: O(1)回答查询。
辅助空间: O(n)
替代性更短实施
C++
#include
using namespace std;
vector no_NGN(int arr[], int n)
{
vector nxt;
// use of stl stack in c++
stack s;
nxt.push_back(0);
// push the (n-1)th index to the stack
s.push(n - 1);
// traverse in reverse order
for (int i = n - 2; i >= 0; i--) {
while (!s.empty() && arr[i] >= arr[s.top()])
s.pop();
// if no element is greater than arr[i] the
// number of NGEs to right is 0
if (s.empty())
nxt.push_back(0);
else
// number of NGEs to right of arr[i] is
// one greater than the number of NGEs to right
// of higher number to its right
nxt.push_back(nxt[n - s.top() - 1] + 1);
s.push(i);
}
// reverse again because values are in reverse order
reverse(nxt.begin(), nxt.end());
// returns the vector of number of next
// greater elements to the right of each index.
return nxt;
}
int main()
{
int n = 8;
int arr[] = { 3, 4, 2, 7, 5, 8, 10, 6 };
vector nxt = no_NGN(arr, n);
// query 1 answered
cout << nxt[3] << endl;
// query 2 answered
cout << nxt[6] << endl;
// query 3 answered
cout << nxt[1] << endl;
return 0;
}
Java
import java.util.*;
class GFG{
static Vector no_NGN(int arr[], int n)
{
Vector nxt = new Vector<>();
// use of stl stack in Java
Stack s = new Stack<>();
nxt.add(0);
// push the (n-1)th index to the stack
s.add(n - 1);
// traverse in reverse order
for (int i = n - 2; i >= 0; i--)
{
while (!s.isEmpty() && arr[i] >= arr[s.peek()])
s.pop();
// if no element is greater than arr[i] the
// number of NGEs to right is 0
if (s.isEmpty())
nxt.add(0);
else
// number of NGEs to right of arr[i] is
// one greater than the number of NGEs to right
// of higher number to its right
nxt.add(nxt.get(n - s.peek() - 1 ) + 1);
s.add(i);
}
// reverse again because values are in reverse order
Collections.reverse(nxt);
// returns the vector of number of next
// greater elements to the right of each index.
return nxt;
}
// Driver code
public static void main(String[] args)
{
int n = 8;
int arr[] = { 3, 4, 2, 7, 5, 8, 10, 6 };
Vector nxt = no_NGN(arr, n);
// query 1 answered
System.out.print(nxt.get(3) +"\n");
// query 2 answered
System.out.print(nxt.get(6) +"\n");
// query 3 answered
System.out.print(nxt.get(1) +"\n");
}
}
// This code is contributed by Rajput-Ji
C#
using System;
using System.Collections.Generic;
public class GFG{
static List no_NGN(int []arr, int n)
{
List nxt = new List();
// use of stl stack in Java
Stack s = new Stack();
nxt.Add(0);
// push the (n-1)th index to the stack
s.Push(n - 1);
// traverse in reverse order
for (int i = n - 2; i >= 0; i--)
{
while (s.Count!=0 && arr[i] >= arr[s.Peek()])
s.Pop();
// if no element is greater than arr[i] the
// number of NGEs to right is 0
if (s.Count == 0)
nxt.Add(0);
else
// number of NGEs to right of arr[i] is
// one greater than the number of NGEs to right
// of higher number to its right
nxt.Add(nxt[n - s.Peek() - 1 ] + 1);
s.Push(i);
}
// reverse again because values are in reverse order
nxt.Reverse();
// returns the vector of number of next
// greater elements to the right of each index.
return nxt;
}
// Driver code
public static void Main(String[] args)
{
int n = 8;
int []arr = { 3, 4, 2, 7, 5, 8, 10, 6 };
List nxt = no_NGN(arr, n);
// query 1 answered
Console.Write(nxt[3] +"\n");
// query 2 answered
Console.Write(nxt[6] +"\n");
// query 3 answered
Console.Write(nxt[1] +"\n");
}
}
// This code iscontributed by aashish1995
输出
2
0
3