📌  相关文章
📜  在数组左侧找到最接近的较小数字

📅  最后修改于: 2021-04-29 18:15:07             🧑  作者: Mango

给定整数数组,请为每个元素找到最接近的较小数字,以使较小的元素位于左侧。

例子:

Input:  arr[] = {1, 6, 4, 10, 2, 5}
Output:         {_, 1, 1,  4, 1, 2}
First element ('1') has no element on left side. For 6, 
there is only one smaller element on left side '1'. 
For 10, there are three smaller elements on left side (1,
6 and 4), nearest among the three elements is 4.

Input: arr[] = {1, 3, 0, 2, 5}
Output:        {_, 1, _, 0, 2}

预期时间复杂度为O(n)。

一个简单的解决方案是使用两个嵌套循环。外循环从第二个元素开始,内循环转到外循环选择的元素左侧的所有元素,并在找到较小的元素后立即停止。

C++
// C++ implementation of simple algorithm to find
// smaller element on left side
#include 
using namespace std;
 
// Prints smaller elements on left side of every element
void printPrevSmaller(int arr[], int n)
{
    // Always print empty or '_' for first element
    cout << "_, ";
 
    // Start from second element
    for (int i=1; i=0; j--)
        {
            if (arr[j] < arr[i])
            {
                cout << arr[j] << ", ";
                break;
            }
        }
 
        // If there is no smaller element on left of 'i'
        if (j == -1)
           cout << "_, " ;
    }
}
 
/* Driver program to test insertion sort */
int main()
{
    int arr[] = {1, 3, 0, 2, 5};
    int n = sizeof(arr)/sizeof(arr[0]);
    printPrevSmaller(arr, n);
    return 0;
}


Java
// Java implementation of simple
// algorithm to find smaller
// element on left side
import java.io.*;
class GFG {
 
// Prints smaller elements on
// left side of every element
static void printPrevSmaller(int []arr, int n)
{
     
    // Always print empty or '_'
    // for first element
    System.out.print( "_, ");
 
    // Start from second element
    for (int i = 1; i < n; i++)
    {
        // look for smaller
        // element on left of 'i'
        int j;
        for(j = i - 1; j >= 0; j--)
        {
            if (arr[j] < arr[i])
            {
                System.out.print(arr[j] + ", ");
                break;
            }
        }
 
        // If there is no smaller
        // element on left of 'i'
        if (j == -1)
        System.out.print( "_, ") ;
    }
}
 
    // Driver Code
    public static void main (String[] args)
    {
        int []arr = {1, 3, 0, 2, 5};
        int n = arr.length;
        printPrevSmaller(arr, n);
    }
}
 
// This code is contributed by anuj_67.


Python3
# Python 3 implementation of simple
# algorithm to find smaller element
# on left side
 
# Prints smaller elements on left
# side of every element
def printPrevSmaller(arr, n):
 
    # Always print empty or '_' for
    # first element
    print("_, ", end="")
 
    # Start from second element
    for i in range(1, n ):
     
        # look for smaller element
        # on left of 'i'
        for j in range(i-1 ,-2 ,-1):
         
            if (arr[j] < arr[i]):
             
                print(arr[j] ,", ",
                            end="")
                break
 
        # If there is no smaller
        # element on left of 'i'
        if (j == -1):
            print("_, ", end="")
 
# Driver program to test insertion
# sort
arr = [1, 3, 0, 2, 5]
n = len(arr)
printPrevSmaller(arr, n)
 
# This code is contributed by
# Smitha


C#
// C# implementation of simple
// algorithm to find smaller
// element on left side
using System;
 
class GFG {
 
    // Prints smaller elements on
    // left side of every element
    static void printPrevSmaller(int []arr,
                                    int n)
    {
         
        // Always print empty or '_'
        // for first element
        Console.Write( "_, ");
     
        // Start from second element
        for (int i = 1; i < n; i++)
        {
            // look for smaller
            // element on left of 'i'
            int j;
            for(j = i - 1; j >= 0; j--)
            {
                if (arr[j] < arr[i])
                {
                    Console.Write(arr[j]
                                + ", ");
                    break;
                }
            }
     
            // If there is no smaller
            // element on left of 'i'
            if (j == -1)
            Console.Write( "_, ") ;
        }
    }
 
    // Driver Code
    public static void Main ()
    {
        int []arr = {1, 3, 0, 2, 5};
        int n = arr.Length;
        printPrevSmaller(arr, n);
    }
}
 
// This code is contributed by anuj_67.


PHP
= 0; $j--)
        {
            if ($arr[$j] < $arr[$i])
            {
                echo $arr[$j] , ", ";
                break;
            }
        }
 
        // If there is no smaller
        // element on left of 'i'
        if ($j == -1)
        echo "_, " ;
    }
}
 
    // Driver Code
    $arr = array(1, 3, 0, 2, 5);
    $n = count($arr);
    printPrevSmaller($arr, $n);
 
// This code is contributed by anuj_67.
?>


Javascript


C++
// C++ implementation of efficient algorithm to find
// smaller element on left side
#include 
#include 
using namespace std;
 
// Prints smaller elements on left side of every element
void printPrevSmaller(int arr[], int n)
{
    // Create an empty stack
    stack S;
 
    // Traverse all array elements
    for (int i=0; i= arr[i])
            S.pop();
 
        // If all elements in S were greater than arr[i]
        if (S.empty())
            cout << "_, ";
        else  //Else print the nearest smaller element
            cout << S.top() << ", ";
 
        // Push this element
        S.push(arr[i]);
    }
}
 
/* Driver program to test insertion sort */
int main()
{
    int arr[] = {1, 3, 0, 2, 5};
    int n = sizeof(arr)/sizeof(arr[0]);
    printPrevSmaller(arr, n);
    return 0;
}


Java
import java.util.Stack;
 
//Java implementation of efficient algorithm to find
// smaller element on left side
class GFG {
 
// Prints smaller elements on left side of every element
    static void printPrevSmaller(int arr[], int n) {
        // Create an empty stack
        Stack S = new Stack<>();
 
        // Traverse all array elements
        for (int i = 0; i < n; i++) {
            // Keep removing top element from S while the top
            // element is greater than or equal to arr[i]
            while (!S.empty() && S.peek() >= arr[i]) {
                S.pop();
            }
 
            // If all elements in S were greater than arr[i]
            if (S.empty()) {
                System.out.print("_, ");
            } else //Else print the nearest smaller element
            {
                System.out.print(S.peek() + ", ");
            }
 
            // Push this element
            S.push(arr[i]);
        }
    }
 
    /* Driver program to test insertion sort */
    public static void main(String[] args) {
        int arr[] = {1, 3, 0, 2, 5};
        int n = arr.length;
        printPrevSmaller(arr, n);
    }
}


Python3
# Python3 implementation of efficient
# algorithm to find smaller element
# on left side
import math as mt
 
# Prints smaller elements on left
# side of every element
def printPrevSmaller(arr, n):
 
    # Create an empty stack
    S = list()
 
    # Traverse all array elements
    for i in range(n):
     
        # Keep removing top element from S
        # while the top element is greater
        # than or equal to arr[i]
        while (len(S) > 0 and S[-1] >= arr[i]):
            S.pop()
 
        # If all elements in S were greater
        # than arr[i]
        if (len(S) == 0):
            print("_, ", end = "")
        else: # Else print the nearest
              # smaller element
            print(S[-1], end = ", ")
 
        # Push this element
        S.append(arr[i])
     
# Driver Code
arr = [ 1, 3, 0, 2, 5]
n = len(arr)
printPrevSmaller(arr, n)
 
# This code is contributed by
# Mohit kumar 29


C#
// C# implementation of efficient algorithm to find
// smaller element on left side
using System;
using System.Collections.Generic;
     
public class GFG
{
 
    // Prints smaller elements on left side of every element
    static void printPrevSmaller(int []arr, int n)
    {
        // Create an empty stack
        Stack S = new Stack();
 
        // Traverse all array elements
        for (int i = 0; i < n; i++)
        {
            // Keep removing top element from S while the top
            // element is greater than or equal to arr[i]
            while (S.Count != 0 && S.Peek() >= arr[i])
            {
                S.Pop();
            }
 
            // If all elements in S were greater than arr[i]
            if (S.Count == 0)
            {
                Console.Write("_, ");
            }
            else //Else print the nearest smaller element
            {
                Console.Write(S.Peek() + ", ");
            }
 
            // Push this element
            S.Push(arr[i]);
        }
    }
 
    /* Driver code */
    public static void Main(String[] args)
    {
        int []arr = {1, 3, 0, 2, 5};
        int n = arr.Length;
        printPrevSmaller(arr, n);
    }
}
 
// This code is contributed by Princi Singh


Javascript


输出:

_, 1, _, 0, 2, ,

上述解决方案的时间复杂度为O(n 2 )。
 
可能存在一个可以在O(n)时间内工作的有效解决方案。这个想法是使用堆栈。堆栈用于维护到目前为止已处理的值的子序列,并且小于任何已经处理的后续值。
下面是基于堆栈的算法

Let input sequence be 'arr[]' and size of array be 'n'

1) Create a new empty stack S

2) For every element 'arr[i]' in the input sequence 'arr[]',
   where 'i' goes from 0 to n-1.
    a) while S is nonempty and the top element of 
       S is greater than or equal to 'arr[i]':
           pop S
    
    b) if S is empty:
           'arr[i]' has no preceding smaller value
    c) else:
           the nearest smaller value to 'arr[i]' is 
           the top element of S

    d) push 'arr[i]' onto S

下面是上述算法的实现。

C++

// C++ implementation of efficient algorithm to find
// smaller element on left side
#include 
#include 
using namespace std;
 
// Prints smaller elements on left side of every element
void printPrevSmaller(int arr[], int n)
{
    // Create an empty stack
    stack S;
 
    // Traverse all array elements
    for (int i=0; i= arr[i])
            S.pop();
 
        // If all elements in S were greater than arr[i]
        if (S.empty())
            cout << "_, ";
        else  //Else print the nearest smaller element
            cout << S.top() << ", ";
 
        // Push this element
        S.push(arr[i]);
    }
}
 
/* Driver program to test insertion sort */
int main()
{
    int arr[] = {1, 3, 0, 2, 5};
    int n = sizeof(arr)/sizeof(arr[0]);
    printPrevSmaller(arr, n);
    return 0;
}

Java

import java.util.Stack;
 
//Java implementation of efficient algorithm to find
// smaller element on left side
class GFG {
 
// Prints smaller elements on left side of every element
    static void printPrevSmaller(int arr[], int n) {
        // Create an empty stack
        Stack S = new Stack<>();
 
        // Traverse all array elements
        for (int i = 0; i < n; i++) {
            // Keep removing top element from S while the top
            // element is greater than or equal to arr[i]
            while (!S.empty() && S.peek() >= arr[i]) {
                S.pop();
            }
 
            // If all elements in S were greater than arr[i]
            if (S.empty()) {
                System.out.print("_, ");
            } else //Else print the nearest smaller element
            {
                System.out.print(S.peek() + ", ");
            }
 
            // Push this element
            S.push(arr[i]);
        }
    }
 
    /* Driver program to test insertion sort */
    public static void main(String[] args) {
        int arr[] = {1, 3, 0, 2, 5};
        int n = arr.length;
        printPrevSmaller(arr, n);
    }
}

Python3

# Python3 implementation of efficient
# algorithm to find smaller element
# on left side
import math as mt
 
# Prints smaller elements on left
# side of every element
def printPrevSmaller(arr, n):
 
    # Create an empty stack
    S = list()
 
    # Traverse all array elements
    for i in range(n):
     
        # Keep removing top element from S
        # while the top element is greater
        # than or equal to arr[i]
        while (len(S) > 0 and S[-1] >= arr[i]):
            S.pop()
 
        # If all elements in S were greater
        # than arr[i]
        if (len(S) == 0):
            print("_, ", end = "")
        else: # Else print the nearest
              # smaller element
            print(S[-1], end = ", ")
 
        # Push this element
        S.append(arr[i])
     
# Driver Code
arr = [ 1, 3, 0, 2, 5]
n = len(arr)
printPrevSmaller(arr, n)
 
# This code is contributed by
# Mohit kumar 29

C#

// C# implementation of efficient algorithm to find
// smaller element on left side
using System;
using System.Collections.Generic;
     
public class GFG
{
 
    // Prints smaller elements on left side of every element
    static void printPrevSmaller(int []arr, int n)
    {
        // Create an empty stack
        Stack S = new Stack();
 
        // Traverse all array elements
        for (int i = 0; i < n; i++)
        {
            // Keep removing top element from S while the top
            // element is greater than or equal to arr[i]
            while (S.Count != 0 && S.Peek() >= arr[i])
            {
                S.Pop();
            }
 
            // If all elements in S were greater than arr[i]
            if (S.Count == 0)
            {
                Console.Write("_, ");
            }
            else //Else print the nearest smaller element
            {
                Console.Write(S.Peek() + ", ");
            }
 
            // Push this element
            S.Push(arr[i]);
        }
    }
 
    /* Driver code */
    public static void Main(String[] args)
    {
        int []arr = {1, 3, 0, 2, 5};
        int n = arr.Length;
        printPrevSmaller(arr, n);
    }
}
 
// This code is contributed by Princi Singh

Java脚本


输出:

_, 1, _, 0, 2,