📜  上一个更大的元素

📅  最后修改于: 2021-05-04 08:49:33             🧑  作者: Mango

给定一系列不同的元素,请为每个元素找到先前更大的元素。如果先前的更大元素不存在,则打印-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)。