在数组中查找下一个较小的下一个较大的
给定整数数组,找到数组中每个元素的下一个较小的下一个较大的元素。
注意:不存在较大元素或不存在较大元素中的较小元素的元素,打印-1。
例子:
Input : arr[] = {5, 1, 9, 2, 5, 1, 7}
Output: 2 2 -1 1 -1 -1 -1
Explanation :
Next Greater -> Right Smaller
5 -> 9 9 -> 2
1 -> 9 9 -> 2
9 -> -1 -1 -> -1
2 -> 5 5 -> 1
5 -> 7 7 -> -1
1 -> 7 7 -> -1
7 -> -1 -1 -> -1
Input : arr[] = {4, 8, 2, 1, 9, 5, 6, 3}
Output : 2 5 5 5 -1 3 -1 -1
一个简单的解决方案是遍历所有元素。对于每个元素,找到当前元素的下一个更大的元素,然后为当前的下一个更大的元素找到更小的元素。该解决方案花费的时间为 O(n 2 )。
一个有效的解决方案需要 O(n) 时间。请注意,它是数组中下一个较大元素和下一个较小元素的组合。
Let input array be 'arr[]' and size of array be 'n'
find next greatest element of every element
step 1 : Create an empty stack (S) in which we store the indexes
and NG[] that is user to store the indexes of NGE
of every element.
step 2 : Traverse the array in reverse order
where i goes from (n-1 to 0)
a) While S is nonempty and the top element of
S is smaller than or equal to 'arr[i]':
pop S
b) If S is empty
arr[i] has no greater element
NG[i] = -1
c) else we have next greater element
NG[i] = S.top() // here we store the index of NGE
d). push current element index in stack
S.push(i)
Find Right smaller element of every element
step 3 : create an array RS[] used to store the index of
right smallest element
step 4 : we repeat step (1 & 2) with little bit of
modification in step 1 & 2 .
they are :
a). we use RS[] in place of NG[].
b). In step (2.a)
we pop element form stack S while S is not
empty or the top element of S is greater then
or equal to 'arr[i]'
step 5 . compute all RSE of NGE :
where i goes from 0 to n-1
if NG[ i ] != -1 && RS[ NG [ i]] ! =-1
print arr[RS[NG[i]]]
else
print -1
下面是上述想法的实现
C++
// C++ Program to find Right smaller element of next
// greater element
#include
using namespace std;
// function find Next greater element
void nextGreater(int arr[], int n, int next[], char order)
{
// create empty stack
stack S;
// Traverse all array elements in reverse order
// order == 'G' we compute next greater elements of
// every element
// order == 'S' we compute right smaller element of
// every element
for (int i=n-1; i>=0; i--)
{
// Keep removing top element from S while the top
// element is smaller then or equal to arr[i] (if Key is G)
// element is greater then or equal to arr[i] (if order is S)
while (!S.empty() &&
((order=='G')? arr[S.top()] <= arr[i]:
arr[S.top()] >= arr[i]))
S.pop();
// store the next greater element of current element
if (!S.empty())
next[i] = S.top();
// If all elements in S were smaller than arr[i]
else
next[i] = -1;
// Push this element
S.push(i);
}
}
// Function to find Right smaller element of next greater
// element
void nextSmallerOfNextGreater(int arr[], int n)
{
int NG[n]; // stores indexes of next greater elements
int RS[n]; // stores indexes of right smaller elements
// Find next greater element
// Here G indicate next greater element
nextGreater(arr, n, NG, 'G');
// Find right smaller element
// using same function nextGreater()
// Here S indicate right smaller elements
nextGreater(arr, n, RS, 'S');
// If NG[i] == -1 then there is no smaller element
// on right side. We can find Right smaller of next
// greater by arr[RS[NG[i]]]
for (int i=0; i< n; i++)
{
if (NG[i] != -1 && RS[NG[i]] != -1)
cout << arr[RS[NG[i]]] << " ";
else
cout<<"-1"<<" ";
}
}
// Driver program
int main()
{
int arr[] = {5, 1, 9, 2, 5, 1, 7};
int n = sizeof(arr)/sizeof(arr[0]);
nextSmallerOfNextGreater(arr, n);
return 0;
}
Java
// Java Program to find Right smaller element of next
// greater element
import java.util.Stack;
public class Main {
// function find Next greater element
public static void nextGreater(int arr[], int next[], char order)
{
// create empty stack
Stack stack=new Stack<>();
// Traverse all array elements in reverse order
// order == 'G' we compute next greater elements of
// every element
// order == 'S' we compute right smaller element of
// every element
for (int i=arr.length-1; i>=0; i--)
{
// Keep removing top element from S while the top
// element is smaller then or equal to arr[i] (if Key is G)
// element is greater then or equal to arr[i] (if order is S)
while (!stack.isEmpty() && ((order=='G')? arr[stack.peek()] <= arr[i]:arr[stack.peek()] >= arr[i]))
stack.pop();
// store the next greater element of current element
if (!stack.isEmpty())
next[i] = stack.peek();
// If all elements in S were smaller than arr[i]
else
next[i] = -1;
// Push this element
stack.push(i);
}
}
// Function to find Right smaller element of next greater
// element
public static void nextSmallerOfNextGreater(int arr[])
{
int NG[]=new int[arr.length]; // stores indexes of next greater elements
int RS[]=new int[arr.length]; // stores indexes of right smaller elements
// Find next greater element
// Here G indicate next greater element
nextGreater(arr, NG, 'G');
// Find right smaller element
// using same function nextGreater()
// Here S indicate right smaller elements
nextGreater(arr, RS, 'S');
// If NG[i] == -1 then there is no smaller element
// on right side. We can find Right smaller of next
// greater by arr[RS[NG[i]]]
for (int i=0; i< arr.length; i++)
{
if (NG[i] != -1 && RS[NG[i]] != -1)
System.out.print(arr[RS[NG[i]]]+" ");
else
System.out.print("-1 ");
}
}
public static void main(String args[]) {
int arr[] = {5, 1, 9, 2, 5, 1, 7};
nextSmallerOfNextGreater(arr);
}
}
//This code is contributed by Gaurav Tiwari
Python 3
# Python 3 Program to find Right smaller element of next
# greater element
# function find Next greater element
def nextGreater(arr, n, next, order):
S = []
# Traverse all array elements in reverse order
# order == 'G' we compute next greater elements of
# every element
# order == 'S' we compute right smaller element of
# every element
for i in range(n-1,-1,-1):
# Keep removing top element from S while the top
# element is smaller then or equal to arr[i] (if Key is G)
# element is greater then or equal to arr[i] (if order is S)
while (S!=[] and (arr[S[len(S)-1]] <= arr[i]
if (order=='G') else arr[S[len(S)-1]] >= arr[i] )):
S.pop()
# store the next greater element of current element
if (S!=[]):
next[i] = S[len(S)-1]
# If all elements in S were smaller than arr[i]
else:
next[i] = -1
# Push this element
S.append(i)
# Function to find Right smaller element of next greater
# element
def nextSmallerOfNextGreater(arr, n):
NG = [None]*n # stores indexes of next greater elements
RS = [None]*n # stores indexes of right smaller elements
# Find next greater element
# Here G indicate next greater element
nextGreater(arr, n, NG, 'G')
# Find right smaller element
# using same function nextGreater()
# Here S indicate right smaller elements
nextGreater(arr, n, RS, 'S')
# If NG[i] == -1 then there is no smaller element
# on right side. We can find Right smaller of next
# greater by arr[RS[NG[i]]]
for i in range(n):
if (NG[i] != -1 and RS[NG[i]] != -1):
print(arr[RS[NG[i]]],end=" ")
else:
print("-1",end=" ")
# Driver program
if __name__=="__main__":
arr = [5, 1, 9, 2, 5, 1, 7]
n = len(arr)
nextSmallerOfNextGreater(arr, n)
# this code is contributed by ChitraNayal
C#
using System;
using System.Collections.Generic;
// C# Program to find Right smaller element of next
// greater element
public class GFG {
// function find Next greater element
public static void nextGreater(int []arr, int []next, char order)
{
// create empty stack
Stack stack=new Stack();
// Traverse all array elements in reverse order
// order == 'G' we compute next greater elements of
// every element
// order == 'S' we compute right smaller element of
// every element
for (int i=arr.Length-1; i>=0; i--)
{
// Keep removing top element from S while the top
// element is smaller then or equal to arr[i] (if Key is G)
// element is greater then or equal to arr[i] (if order is S)
while (stack.Count!=0 && ((order=='G')? arr[stack.Peek()] <= arr[i]:arr[stack.Peek()] >= arr[i]))
stack.Pop();
// store the next greater element of current element
if (stack.Count!=0)
next[i] = stack.Peek();
// If all elements in S were smaller than arr[i]
else
next[i] = -1;
// Push this element
stack.Push(i);
}
}
// Function to find Right smaller element of next greater
// element
public static void nextSmallerOfNextGreater(int []arr)
{
int []NG=new int[arr.Length]; // stores indexes of next greater elements
int []RS=new int[arr.Length]; // stores indexes of right smaller elements
// Find next greater element
// Here G indicate next greater element
nextGreater(arr, NG, 'G');
// Find right smaller element
// using same function nextGreater()
// Here S indicate right smaller elements
nextGreater(arr, RS, 'S');
// If NG[i] == -1 then there is no smaller element
// on right side. We can find Right smaller of next
// greater by arr[RS[NG[i]]]
for (int i=0; i< arr.Length; i++)
{
if (NG[i] != -1 && RS[NG[i]] != -1)
Console.Write(arr[RS[NG[i]]]+" ");
else
Console.Write("-1 ");
}
}
public static void Main() {
int []arr = {5, 1, 9, 2, 5, 1, 7};
nextSmallerOfNextGreater(arr);
}
}
// This code is contributed by PrinciRaj1992
Javascript
输出:
2 2 -1 1 -1 -1 -1