给定一系列不同的元素,请为每个元素找到先前更大的元素。如果先前的更大元素不存在,则打印-1。
例子:
Input : arr[] = {10, 4, 2, 20, 40, 12, 30}
Output : -1, 10, 4, -1, -1, 40, 40
Input : arr[] = {10, 20, 30, 40}
Output : -1, -1, -1, -1
Input : arr[] = {40, 30, 20, 10}
Output : -1, 40, 30, 20
预期时间复杂度:O(n)
一个简单的解决方案是运行两个嵌套循环。外循环一个接一个地选择一个元素。在内部循环中,找到前一个更大的元素。
C++
// C++ program previous greater element
// A naive solution to print previous greater
// element for every element in an array.
#include
using namespace std;
void prevGreater(int arr[], int n)
{
// Previous greater for first element never
// exists, so we print -1.
cout << "-1, ";
// Let us process remaining elements.
for (int i = 1; i < n; i++) {
// Find first element on left side
// that is greater than arr[i].
int j;
for (j = i-1; j >= 0; j--) {
if (arr[i] < arr[j]) {
cout << arr[j] << ", ";
break;
}
}
// If all elements on left are smaller.
if (j == -1)
cout << "-1, ";
}
}
// Driver code
int main()
{
int arr[] = { 10, 4, 2, 20, 40, 12, 30 };
int n = sizeof(arr) / sizeof(arr[0]);
prevGreater(arr, n);
return 0;
}
Java
// Java program previous greater element
// A naive solution to print
// previous greater element
// for every element in an array.
import java.io.*;
import java.util.*;
import java.lang.*;
class GFG
{
static void prevGreater(int arr[],
int n)
{
// Previous greater for
// first element never
// exists, so we print -1.
System.out.print("-1, ");
// Let us process
// remaining elements.
for (int i = 1; i < n; i++)
{
// Find first element on
// left side that is
// greater than arr[i].
int j;
for (j = i-1; j >= 0; j--)
{
if (arr[i] < arr[j])
{
System.out.print(arr[j] + ", ");
break;
}
}
// If all elements on
// left are smaller.
if (j == -1)
System.out.print("-1, ");
}
}
// Driver Code
public static void main(String[] args)
{
int arr[] = {10, 4, 2, 20, 40, 12, 30};
int n = arr.length;
prevGreater(arr, n);
}
}
Python 3
# Python 3 program previous greater element
# A naive solution to print previous greater
# element for every element in an array.
def prevGreater(arr, n) :
# Previous greater for first element never
# exists, so we print -1.
print("-1",end = ", ")
# Let us process remaining elements.
for i in range(1, n) :
flag = 0
# Find first element on left side
# that is greater than arr[i].
for j in range(i-1, -1, -1) :
if arr[i] < arr[j] :
print(arr[j],end = ", ")
flag = 1
break
# If all elements on left are smaller.
if j == 0 and flag == 0:
print("-1",end = ", ")
# Driver code
if __name__ == "__main__" :
arr = [10, 4, 2, 20, 40, 12, 30]
n = len(arr)
prevGreater(arr, n)
# This code is contributed by ANKITRAI1
C#
// C# program previous greater element
// A naive solution to print
// previous greater element
// for every element in an array.
using System;
class GFG
{
static void prevGreater(int[] arr,
int n)
{
// Previous greater for
// first element never
// exists, so we print -1.
Console.Write("-1, ");
// Let us process
// remaining elements.
for (int i = 1; i < n; i++)
{
// Find first element on
// left side that is
// greater than arr[i].
int j;
for (j = i-1; j >= 0; j--)
{
if (arr[i] < arr[j])
{
Console.Write(arr[j] + ", ");
break;
}
}
// If all elements on
// left are smaller.
if (j == -1)
Console.Write("-1, ");
}
}
// Driver Code
public static void Main()
{
int[] arr = {10, 4, 2, 20, 40, 12, 30};
int n = arr.Length;
prevGreater(arr, n);
}
}
PHP
= 0; $j--)
{
if ($arr[$i] < $arr[$j])
{
echo($arr[$j]);
echo( ", ");
break;
}
}
// If all elements on left are smaller.
if ($j == -1)
echo("-1, ");
}
}
// Driver code
$arr = array(10, 4, 2, 20, 40, 12, 30);
$n = sizeof($arr) ;
prevGreater($arr, $n);
//This code is contributed by Shivi_Aggarwal.
?>
C++
// C++ program previous greater element
// An efficient solution to print previous greater
// element for every element in an array.
#include
using namespace std;
void prevGreater(int arr[], int n)
{
// Create a stack and push index of first element
// to it
stack s;
s.push(arr[0]);
// Previous greater for first element is always -1.
cout << "-1, ";
// Traverse remaining elements
for (int i = 1; i < n; i++) {
// Pop elements from stack while stack is not empty
// and top of stack is smaller than arr[i]. We
// always have elements in decreasing order in a
// stack.
while (s.empty() == false && s.top() < arr[i])
s.pop();
// If stack becomes empty, then no element is greater
// on left side. Else top of stack is previous
// greater.
s.empty() ? cout << "-1, " : cout << s.top() << ", ";
s.push(arr[i]);
}
}
// Driver code
int main()
{
int arr[] = { 10, 4, 2, 20, 40, 12, 30 };
int n = sizeof(arr) / sizeof(arr[0]);
prevGreater(arr, n);
return 0;
}
Java
// Java program previous greater element
// An efficient solution to
// print previous greater
// element for every element
// in an array.
import java.io.*;
import java.util.*;
import java.lang.*;
class GFG
{
static void prevGreater(int arr[],
int n)
{
// Create a stack and push
// index of first element
// to it
Stack s = new Stack();
s.push(arr[0]);
// Previous greater for
// first element is always -1.
System.out.print("-1, ");
// Traverse remaining elements
for (int i = 1; i < n; i++)
{
// Pop elements from stack
// while stack is not empty
// and top of stack is smaller
// than arr[i]. We always have
// elements in decreasing order
// in a stack.
while (s.empty() == false &&
s.peek() < arr[i])
s.pop();
// If stack becomes empty, then
// no element is greater on left
// side. Else top of stack is
// previous greater.
if (s.empty() == true)
System.out.print("-1, ");
else
System.out.print(s.peek() + ", ");
s.push(arr[i]);
}
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 10, 4, 2, 20, 40, 12, 30 };
int n = arr.length;
prevGreater(arr, n);
}
}
Python3
# Python3 program to print previous greater element
# An efficient solution to print previous greater
# element for every element in an array.
import math as mt
def prevGreater(arr, n):
# Create a stack and push index of
# first element to it
s = list();
s.append(arr[0])
# Previous greater for first element
# is always -1.
print("-1, ", end = "")
# Traverse remaining elements
for i in range(1, n):
# Pop elements from stack while stack is
# not empty and top of stack is smaller
# than arr[i]. We always have elements in
# decreasing order in a stack.
while (len(s) > 0 and s[-1] < arr[i]):
s.pop()
# If stack becomes empty, then no element
# is greater on left side. Else top of stack
# is previous greater.
if len(s) == 0:
print("-1, ", end = "")
else:
print(s[-1], ", ", end = "")
s.append(arr[i])
# Driver code
arr = [ 10, 4, 2, 20, 40, 12, 30 ]
n = len(arr)
prevGreater(arr, n)
# This code is contributed by
# mohit kumar 29
C#
// C# program previous greater element
// An efficient solution to
// print previous greater
// element for every element
// in an array.
using System;
using System.Collections.Generic;
class GFG
{
static void prevGreater(int []arr,
int n)
{
// Create a stack and push
// index of first element
// to it
Stack s = new Stack();
s.Push(arr[0]);
// Previous greater for
// first element is always -1.
Console.Write("-1, ");
// Traverse remaining elements
for (int i = 1; i < n; i++)
{
// Pop elements from stack
// while stack is not empty
// and top of stack is smaller
// than arr[i]. We always have
// elements in decreasing order
// in a stack.
while (s.Count != 0 &&
s.Peek() < arr[i])
s.Pop();
// If stack becomes empty, then
// no element is greater on left
// side. Else top of stack is
// previous greater.
if (s.Count == 0)
Console.Write("-1, ");
else
Console.Write(s.Peek() + ", ");
s.Push(arr[i]);
}
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 10, 4, 2, 20, 40, 12, 30 };
int n = arr.Length;
prevGreater(arr, n);
}
}
// This code is contributed by PrinciRaj1992
输出:
-1, 10, 4, -1, -1, 40, 40
一个有效的解决方案是使用堆栈数据结构。如果我们仔细观察,我们会注意到该问题是库存跨度问题的一种变体。我们在堆栈中保留先前更大的元素。
C++
// C++ program previous greater element
// An efficient solution to print previous greater
// element for every element in an array.
#include
using namespace std;
void prevGreater(int arr[], int n)
{
// Create a stack and push index of first element
// to it
stack s;
s.push(arr[0]);
// Previous greater for first element is always -1.
cout << "-1, ";
// Traverse remaining elements
for (int i = 1; i < n; i++) {
// Pop elements from stack while stack is not empty
// and top of stack is smaller than arr[i]. We
// always have elements in decreasing order in a
// stack.
while (s.empty() == false && s.top() < arr[i])
s.pop();
// If stack becomes empty, then no element is greater
// on left side. Else top of stack is previous
// greater.
s.empty() ? cout << "-1, " : cout << s.top() << ", ";
s.push(arr[i]);
}
}
// Driver code
int main()
{
int arr[] = { 10, 4, 2, 20, 40, 12, 30 };
int n = sizeof(arr) / sizeof(arr[0]);
prevGreater(arr, n);
return 0;
}
Java
// Java program previous greater element
// An efficient solution to
// print previous greater
// element for every element
// in an array.
import java.io.*;
import java.util.*;
import java.lang.*;
class GFG
{
static void prevGreater(int arr[],
int n)
{
// Create a stack and push
// index of first element
// to it
Stack s = new Stack();
s.push(arr[0]);
// Previous greater for
// first element is always -1.
System.out.print("-1, ");
// Traverse remaining elements
for (int i = 1; i < n; i++)
{
// Pop elements from stack
// while stack is not empty
// and top of stack is smaller
// than arr[i]. We always have
// elements in decreasing order
// in a stack.
while (s.empty() == false &&
s.peek() < arr[i])
s.pop();
// If stack becomes empty, then
// no element is greater on left
// side. Else top of stack is
// previous greater.
if (s.empty() == true)
System.out.print("-1, ");
else
System.out.print(s.peek() + ", ");
s.push(arr[i]);
}
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 10, 4, 2, 20, 40, 12, 30 };
int n = arr.length;
prevGreater(arr, n);
}
}
Python3
# Python3 program to print previous greater element
# An efficient solution to print previous greater
# element for every element in an array.
import math as mt
def prevGreater(arr, n):
# Create a stack and push index of
# first element to it
s = list();
s.append(arr[0])
# Previous greater for first element
# is always -1.
print("-1, ", end = "")
# Traverse remaining elements
for i in range(1, n):
# Pop elements from stack while stack is
# not empty and top of stack is smaller
# than arr[i]. We always have elements in
# decreasing order in a stack.
while (len(s) > 0 and s[-1] < arr[i]):
s.pop()
# If stack becomes empty, then no element
# is greater on left side. Else top of stack
# is previous greater.
if len(s) == 0:
print("-1, ", end = "")
else:
print(s[-1], ", ", end = "")
s.append(arr[i])
# Driver code
arr = [ 10, 4, 2, 20, 40, 12, 30 ]
n = len(arr)
prevGreater(arr, n)
# This code is contributed by
# mohit kumar 29
C#
// C# program previous greater element
// An efficient solution to
// print previous greater
// element for every element
// in an array.
using System;
using System.Collections.Generic;
class GFG
{
static void prevGreater(int []arr,
int n)
{
// Create a stack and push
// index of first element
// to it
Stack s = new Stack();
s.Push(arr[0]);
// Previous greater for
// first element is always -1.
Console.Write("-1, ");
// Traverse remaining elements
for (int i = 1; i < n; i++)
{
// Pop elements from stack
// while stack is not empty
// and top of stack is smaller
// than arr[i]. We always have
// elements in decreasing order
// in a stack.
while (s.Count != 0 &&
s.Peek() < arr[i])
s.Pop();
// If stack becomes empty, then
// no element is greater on left
// side. Else top of stack is
// previous greater.
if (s.Count == 0)
Console.Write("-1, ");
else
Console.Write(s.Peek() + ", ");
s.Push(arr[i]);
}
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 10, 4, 2, 20, 40, 12, 30 };
int n = arr.Length;
prevGreater(arr, n);
}
}
// This code is contributed by PrinciRaj1992
输出:
-1, 10, 4, -1, -1, 40, 40
时间复杂度: O(n)。乍一看似乎比O(n)还多。如果我们仔细观察,可以观察到数组的每个元素最多只能从堆栈中添加和删除一次。因此,总共最多只能执行2n次操作。假设堆栈操作花费O(1)时间,那么我们可以说时间复杂度为O(n)。
辅助空间:最坏情况下,当所有元素以降序排序时,为O(n)。