📌  相关文章
📜  数组中每个元素的左侧最近最大值或相同值

📅  最后修改于: 2021-05-24 22:45:14             🧑  作者: Mango

给定一个整数数组,在每个元素的左边找到最接近的(不考虑距离,但考虑值)更大或相同的值。如果元素的左侧没有更大或相同的值,则打印-1。

例子:

一个简单的解决方案是运行两个嵌套循环。我们一个接一个地选择一个外部元素。对于每个拾取的元素,我们向其左侧移动并找到最接近的(按值)较大的元素。该解决方案的时间复杂度为O(n * n)

一个有效的解决方案是使用自我平衡BST(按照C++中的设置和Java的TreeSet的实现)。在自平衡BST中,我们可以在O(Log n)时间执行插入操作和最接近的较大操作。

我们在C++中使用lower_bound()来查找最接近的更大元素。此函数以Log n时间为一组。

C++
// C++ implementation of efficient algorithm to find
// greater or same element on left side
#include 
#include 
using namespace std;
  
// Prints greater elements on left side of every element
void printPrevGreater(int arr[], int n)
{
    set s;
    for (int i = 0; i < n; i++) {
  
        // First search in set
        auto it = s.lower_bound(arr[i]);
        if (it == s.end()) // If no greater found
            cout << "-1"
                 << " ";
        else
            cout << *it << " ";
  
        // Then insert
        s.insert(arr[i]);
    }
}
  
/* Driver program to test insertion sort */
int main()
{
    int arr[] = { 10, 5, 11, 10, 20, 12 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printPrevGreater(arr, n);
    return 0;
}


Java
// Java implementation of efficient algorithm
// to find greater or same element on left side
import java.util.TreeSet;
  
class GFG {
  
    // Prints greater elements on left side
    // of every element
    static void printPrevGreater(int[] arr, int n)
    {
        TreeSet ts = new TreeSet<>();
        for (int i = 0; i < n; i++) {
            Integer c = ts.ceiling(arr[i]);
            if (c == null) // If no greater found
                System.out.print(-1 + " ");
            else
                System.out.print(c + " ");
  
            // Then insert
            ts.add(arr[i]);
        }
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int[] arr = { 10, 5, 11, 10, 20, 12 };
        int n = arr.length;
        printPrevGreater(arr, n);
    }
}
  
// This code is contributed by
// sanjeev2552


Python3
# Python3 implementation of efficient algorithm 
# to find greater or same element on left side 
  
# Prints greater elements 
# on left side of every element 
def printPrevGreater(arr, n): 
  
    s = set()
    for i in range(0, n): 
  
        # First search in set 
        it = [x for x in s if x >= arr[i]] 
        if len(it) == 0: # If no greater found 
            print("-1", end = " ") 
        else:                 
            print(min(it), end = " ")         
  
        # Then insert 
        s.add(arr[i]) 
  
# Driver Code
if __name__ == "__main__": 
  
    arr = [10, 5, 11, 10, 20, 12] 
    n = len(arr) 
    printPrevGreater(arr, n) 
      
# This code is contributed by Rituraj Jain


C#
// C# implementation of efficient algorithm 
// to find greater or same element on left side 
using System; 
using System.Collections.Generic; 
  
class GFG { 
  
    // To get the minimum value
    static int minimum(SortedSet ss) 
    { 
        int min = int.MaxValue; 
  
        foreach(int i in ss) if (i < min) 
            min = i; 
  
        return min; 
    } 
  
    // Prints greater elements on left side 
    // of every element 
    static void printPrevGreater(int[] arr, int n) 
    { 
        SortedSet s = new SortedSet(); 
  
        for (int i = 0; i < n; i++) { 
            SortedSet ss = new SortedSet(); 
  
            // First search in set 
            foreach(int x in s) if (x >= arr[i]) 
                ss.Add(x); 
  
            if (ss.Count == 0) // If no greater found 
                Console.Write(-1 + " "); 
            else
                Console.Write(minimum(ss) + " "); 
  
            // Then insert 
            s.Add(arr[i]); 
        } 
    } 
  
    // Driver Code 
    public static void Main(String[] args) 
    { 
        int[] arr = { 10, 5, 11, 10, 20, 12 }; 
        int n = arr.Length; 
        printPrevGreater(arr, n); 
    } 
} 
  
// This code is contributed by PrinciRaj1992


输出:
-1 10 -1 10 -1 20

时间复杂度:O(n Log n)