📌  相关文章
📜  下一个较小的元素

📅  最后修改于: 2021-04-23 08:07:32             🧑  作者: Mango

给定一个数组,为每个元素打印下一个较小元素(NSE)。元素x的Smaller small element是数组x中右侧第一个较小的元素。不存在较小元素的元素(在右侧),将下一个较小元素视为-1。
例子:
a)对于任何数组,最右边的元素总是下一个较小的元素为-1。
b)对于按升序排序的数组,所有元素的下一个较小元素为-1。
c)对于输入数组[4、8、5、2、25} ,每个元素的下一个较小元素如下。

Element       NSE
   4      -->   2
   8      -->   5
   5      -->   2
   2      -->   -1
   25     -->   -1

d)对于输入数组[13,7,6,12},每个元素的下一个较小元素如下。

Element        NSE
   13      -->    7
   7       -->    6
   6       -->    -1
   12     -->     -1

方法1(简单)
使用两个循环:外循环一个接一个地拾取所有元素。内循环为外循环选取的元素寻找第一个较小的元素。如果找到较小的元素,则该元素将作为下一个被打印,否则将打印-1。
感谢Sachin提供以下代码。

C++
// Simple C++ program to print
// next smaller elements in a given array
#include "bits/stdc++.h"
using namespace std;
 
/* prints element and NSE pair
for all elements of arr[] of size n */
void printNSE(int arr[], int n)
{
    int next, i, j;
    for (i = 0; i < n; i++)
    {
        next = -1;
        for (j = i + 1; j < n; j++)
        {
            if (arr[i] > arr[j])
            {
                next = arr[j];
                break;
            }
        }
        cout << arr[i] << " -- "
             << next << endl;
    }
}
 
// Driver Code
int main()
{
    int arr[]= {11, 13, 21, 3};
    int n = sizeof(arr) / sizeof(arr[0]);
    printNSE(arr, n);
    return 0;
}
 
// This code is contributed by shivanisinghss2110


C
// Simple C program to print next smaller elements
// in a given array
#include
 
/* prints element and NSE pair for all elements of
arr[] of size n */
void printNSE(int arr[], int n)
{
    int next, i, j;
    for (i=0; i arr[j])
            {
                next = arr[j];
                break;
            }
        }
        printf("%d -- %d\n", arr[i], next);
    }
}
 
int main()
{
    int arr[]= {11, 13, 21, 3};
    int n = sizeof(arr)/sizeof(arr[0]);
    printNSE(arr, n);
    return 0;
}


Java
// Simple Java program to print next
// smaller elements in a given array
 
class Main {
    /* prints element and NSE pair for
     all elements of arr[] of size n */
    static void printNSE(int arr[], int n)
    {
        int next, i, j;
        for (i = 0; i < n; i++) {
            next = -1;
            for (j = i + 1; j < n; j++) {
                if (arr[i] > arr[j]) {
                    next = arr[j];
                    break;
                }
            }
            System.out.println(arr[i] + " -- " + next);
        }
    }
 
    public static void main(String args[])
    {
        int arr[] = { 11, 13, 21, 3 };
        int n = arr.length;
        printNSE(arr, n);
    }
}


Python
# Function to print element and NSE pair for all elements of list
def printNSE(arr):
 
    for i in range(0, len(arr), 1):
 
        next = -1
        for j in range(i + 1, len(arr), 1):
            if arr[i] > arr[j]:
                next = arr[j]
                break
             
        print(str(arr[i]) + " -- " + str(next))
 
# Driver program to test above function
arr = [11, 13, 21, 3]
printNSE(arr)
 
# This code is contributed by Sunny Karira


C#
// Simple C# program to print next
// smaller elements in a given array
using System;
 
class GFG {
 
    /* prints element and NSE pair for
    all elements of arr[] of size n */
    static void printNSE(int[] arr, int n)
    {
        int next, i, j;
        for (i = 0; i < n; i++) {
            next = -1;
            for (j = i + 1; j < n; j++) {
                if (arr[i] > arr[j]) {
                    next = arr[j];
                    break;
                }
            }
            Console.WriteLine(arr[i] + " -- " + next);
        }
    }
 
    // driver code
    public static void Main()
    {
        int[] arr = { 11, 13, 21, 3 };
        int n = arr.Length;
 
        printNSE(arr, n);
    }
}
 
// This code is contributed by Sam007


PHP
 $arr[$j])
            {
                $next = $arr[$j];
                break;
            }
        }
        echo $arr[$i]." -- ". $next."\n";
         
    }
}
 
    // Driver Code
    $arr= array(11, 13, 21, 3);
    $n = count($arr);
    printNSE($arr, $n);
     
// This code is contributed by Sam007
?>


C++
// A Stack based C++ program to find next
// smaller element for all array elements.
#include 
 
using namespace std;
 
/* prints element and NSE pair for all
elements of arr[] of size n */
void printNSE(int arr[], int n)
{
    stack s;
 
    /* push the first element to stack */
    s.push(arr[0]);
 
    // iterate for rest of the elements
    for (int i = 1; i < n; i++) {
 
        if (s.empty()) {
            s.push(arr[i]);
            continue;
        }
 
        /* if stack is not empty, then
       pop an element from stack.
       If the popped element is greater
       than next, then
    a) print the pair
    b) keep popping while elements are
    greater and stack is not empty */
        while (s.empty() == false && s.top() > arr[i]) {
            cout << s.top() << " --> " << arr[i] << endl;
            s.pop();
        }
 
        /* push next to stack so that we can find
    next smaller for it */
        s.push(arr[i]);
    }
 
    /* After iterating over the loop, the remaining
  elements in stack do not have the next smaller
  element, so print -1 for them */
    while (s.empty() == false) {
        cout << s.top() << " --> " << -1 << endl;
        s.pop();
    }
}
 
/* Driver program to test above functions */
int main()
{
    int arr[] = { 11, 13, 21, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printNSE(arr, n);
    return 0;
}


Java
// A Stack based Java program to find next
// smaller element for all array elements.
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG
{
    /* prints element and NSE pair for all
    elements of arr[] of size n */
    public static void printNSE(int arr[], int n)
    {
        Stack s = new Stack();
         
        /* push the first element to stack */
        s.push(arr[0]);
         
        // iterate for rest of the elements
        for (int i = 1; i < n; i++) {
 
        if (s.empty()) {
            s.push(arr[i]);
            continue;
        }
     
         
        /* if stack is not empty, then
        pop an element from stack.
        If the popped element is greater
        than next, then
        a) print the pair
        b) keep popping while elements are
        greater and stack is not empty */
    while (s.empty() == false && s.peek() > arr[i]) {
            System.out.println(s.peek() + " --> " + arr[i]);
            s.pop();
        }
         
        /* push next to stack so that we can find
        next smaller for it */
        s.push(arr[i]);
        }
         
        /* After iterating over the loop, the remaining
        elements in stack do not have the next smaller
        element, so print -1 for them */
            while (s.empty() == false) {
        System.out.println(s.peek() + " --> " + "-1");
        s.pop();
        }
    }
    /* Driver program to test above functions */
    public static void main (String[] args) {
        int arr[] = { 11, 13, 21, 3};
        int n = arr.length;
        printNSE(arr, n);
    }
}


C#
// A Stack based C# program to find next
// smaller element for all array elements.
using System;
using System.Collections.Generic;
public class GFG
{
    /* prints element and NSE pair for all
    elements of arr[] of size n */
    public static void printNSE(int []arr, int n)
    {
        Stack s = new Stack();
          
        /* push the first element to stack */
        s.Push(arr[0]);
          
        // iterate for rest of the elements
        for (int i = 1; i < n; i++) {
  
        if (s.Count==0) {
            s.Push(arr[i]);
            continue;
        }
      
          
        /* if stack is not empty, then
        pop an element from stack.
        If the popped element is greater
        than next, then
        a) print the pair
        b) keep popping while elements are
        greater and stack is not empty */
    while (s.Count !=0 && s.Peek() > arr[i]) {
            Console.WriteLine(s.Peek() + " --> " + arr[i]);
            s.Pop();
        }
          
        /* push next to stack so that we can find
        next smaller for it */
        s.Push(arr[i]);
        }
          
        /* After iterating over the loop, the remaining
        elements in stack do not have the next smaller
        element, so print -1 for them */
            while (s.Count!=0) {
        Console.WriteLine(s.Peek() + " --> " + "-1");
        s.Pop();
        }
    }
    /* Driver program to test above functions */
    public static void Main () {
        int []arr = { 11, 13, 21, 3};
        int n = arr.Length;
        printNSE(arr, n);
    }
}
//This code is contributed by PrinciRaj1992


C++
// A Stack based C++ program to find next
// smaller element for all array elements
// in same order as input.
#include 
using namespace std;
 
/* prints element and NSE pair for all
elements of arr[] of size n */
void printNSE(int arr[], int n)
{
    stack s;
    unordered_map mp;
 
    /* push the first element to stack */
    s.push(arr[0]);
     
 
    // iterate for rest of the elements
    for (int i = 1; i < n; i++) {
 
        if (s.empty()) {
            s.push(arr[i]);
            continue;
        }
 
        /* if stack is not empty, then
       pop an element from stack.
       If the popped element is greater
       than next, then
    a) print the pair
    b) keep popping while elements are
    greater and stack is not empty */
        while (s.empty() == false && s.top() > arr[i]) {
            mp[s.top()] = arr[i];
            s.pop();
        }
 
        /* push next to stack so that we can find
    next smaller for it */
        s.push(arr[i]);
    }
 
    /* After iterating over the loop, the remaining
  elements in stack do not have the next smaller
  element, so print -1 for them */
    while (s.empty() == false) {
         mp[s.top()] = -1;
        s.pop();
    }
 
    for (int i=0; i " << mp[arr[i]] << endl;
}
 
/* Driver program to test above functions */
int main()
{
    int arr[] = { 11, 13, 21, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printNSE(arr, n);
    return 0;
}


Java
// A Stack based Java program to find next
// smaller element for all array elements
// in same order as input.
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG
{
    /* prints element and NSE pair for all
    elements of arr[] of size n */
public static void printNSE(int arr[], int n)
{
    Stack s = new Stack();
    HashMap mp = new HashMap();
         
    /* push the first element to stack */
    s.push(arr[0]);
         
         
    // iterate for rest of the elements
    for (int i = 1; i < n; i++) {
 
        if (s.empty()) {
            s.push(arr[i]);
            continue;
        }
         
         
        /* if stack is not empty, then
    pop an element from stack.
    If the popped element is greater
    than next, then
    a) print the pair
    b) keep popping while elements are
    greater and stack is not empty */
     
    while (s.empty() == false && s.peek() > arr[i]) {
            mp.put(s.peek(), arr[i]);
            s.pop();
        }
         
        /* push next to stack so that we can find
        next smaller for it */
        s.push(arr[i]);
    }
         
         
         
    /* After iterating over the loop, the remaining
    elements in stack do not have the next smaller
    element, so print -1 for them */
    while (s.empty() == false) {
        mp.put(s.peek(), -1);
        s.pop();
    }
     
     
    for (int i=0; i " + mp.get(arr[i]));
}
     
    /* Driver program to test above functions */
    public static void main (String[] args) {
        int arr[] = { 11, 13, 21, 3};
        int n = arr.length;
        printNSE(arr, n);
    }
}


C#
// A Stack based C# program to find next
// smaller element for all array elements
// in same order as input.using System;
using System;
using System.Collections.Generic;
 
class GFG
{
    /* prints element and NSE pair for all
    elements of arr[] of size n */
    public static void printNSE(int []arr, int n)
    {
        Stack s = new Stack();
        Dictionary mp = new Dictionary();
 
        /* push the first element to stack */
        s.Push(arr[0]);
 
 
        // iterate for rest of the elements
        for (int i = 1; i < n; i++)
        {
            if (s.Count==0)
            {
                s.Push(arr[i]);
                continue;
            }
            /* if stack is not empty, then
            pop an element from stack.
            If the popped element is greater
            than next, then
            a) print the pair
            b) keep popping while elements are
            greater and stack is not empty */
            while (s.Count != 0 && s.Peek() > arr[i])
            {
                mp.Add(s.Peek(), arr[i]);
                s.Pop();
            }
 
            /* push next to stack so that we can find
            next smaller for it */
            s.Push(arr[i]);
        }
 
 
 
        /* After iterating over the loop, the remaining
        elements in stack do not have the next smaller
        element, so print -1 for them */
        while (s.Count != 0)
        {
            mp.Add(s.Peek(), -1);
            s.Pop();
        }
 
 
        for (int i = 0; i < n; i++)
        Console.WriteLine(arr[i] + " ---> " + mp[arr[i]]);
    }
     
    // Driver code
    public static void Main()
    {
        int []arr = {11, 13, 21, 3};
        int n = arr.Length;
        printNSE(arr, n);
    }
}
// This code is contributed by
// 29AjayKumar


输出:
11 -- 3
13 -- 3
21 -- 3
3 -- -1

时间复杂度:O(n ^ 2)。最坏的情况发生在所有元素都按降序排序时。
方法2(使用堆栈)
这个问题类似于下一个更大的元素。在这里,我们在堆栈中按递增顺序维护项目(而不是在下一个更大的元素问题中减少)。
1)将第一个元素推入堆栈。
2)一一挑选其余元素,然后按照以下步骤循环进行。
….a)将当前元素标记为next
….b)如果堆栈不为空,则从堆栈中弹出一个元素,然后将其与next进行比较。
….c)如果next小于弹出元素,则next是弹出元素的下一个较小元素。
….d)当弹出的元素大于next时,继续从堆栈中弹出。 next成为所有此类弹出元素的下一个较小元素
3)步骤2中的循环结束后,从堆栈中弹出所有元素,并将-1打印为它们的下一个元素。

C++

// A Stack based C++ program to find next
// smaller element for all array elements.
#include 
 
using namespace std;
 
/* prints element and NSE pair for all
elements of arr[] of size n */
void printNSE(int arr[], int n)
{
    stack s;
 
    /* push the first element to stack */
    s.push(arr[0]);
 
    // iterate for rest of the elements
    for (int i = 1; i < n; i++) {
 
        if (s.empty()) {
            s.push(arr[i]);
            continue;
        }
 
        /* if stack is not empty, then
       pop an element from stack.
       If the popped element is greater
       than next, then
    a) print the pair
    b) keep popping while elements are
    greater and stack is not empty */
        while (s.empty() == false && s.top() > arr[i]) {
            cout << s.top() << " --> " << arr[i] << endl;
            s.pop();
        }
 
        /* push next to stack so that we can find
    next smaller for it */
        s.push(arr[i]);
    }
 
    /* After iterating over the loop, the remaining
  elements in stack do not have the next smaller
  element, so print -1 for them */
    while (s.empty() == false) {
        cout << s.top() << " --> " << -1 << endl;
        s.pop();
    }
}
 
/* Driver program to test above functions */
int main()
{
    int arr[] = { 11, 13, 21, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printNSE(arr, n);
    return 0;
}

Java

// A Stack based Java program to find next
// smaller element for all array elements.
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG
{
    /* prints element and NSE pair for all
    elements of arr[] of size n */
    public static void printNSE(int arr[], int n)
    {
        Stack s = new Stack();
         
        /* push the first element to stack */
        s.push(arr[0]);
         
        // iterate for rest of the elements
        for (int i = 1; i < n; i++) {
 
        if (s.empty()) {
            s.push(arr[i]);
            continue;
        }
     
         
        /* if stack is not empty, then
        pop an element from stack.
        If the popped element is greater
        than next, then
        a) print the pair
        b) keep popping while elements are
        greater and stack is not empty */
    while (s.empty() == false && s.peek() > arr[i]) {
            System.out.println(s.peek() + " --> " + arr[i]);
            s.pop();
        }
         
        /* push next to stack so that we can find
        next smaller for it */
        s.push(arr[i]);
        }
         
        /* After iterating over the loop, the remaining
        elements in stack do not have the next smaller
        element, so print -1 for them */
            while (s.empty() == false) {
        System.out.println(s.peek() + " --> " + "-1");
        s.pop();
        }
    }
    /* Driver program to test above functions */
    public static void main (String[] args) {
        int arr[] = { 11, 13, 21, 3};
        int n = arr.length;
        printNSE(arr, n);
    }
}

C#

// A Stack based C# program to find next
// smaller element for all array elements.
using System;
using System.Collections.Generic;
public class GFG
{
    /* prints element and NSE pair for all
    elements of arr[] of size n */
    public static void printNSE(int []arr, int n)
    {
        Stack s = new Stack();
          
        /* push the first element to stack */
        s.Push(arr[0]);
          
        // iterate for rest of the elements
        for (int i = 1; i < n; i++) {
  
        if (s.Count==0) {
            s.Push(arr[i]);
            continue;
        }
      
          
        /* if stack is not empty, then
        pop an element from stack.
        If the popped element is greater
        than next, then
        a) print the pair
        b) keep popping while elements are
        greater and stack is not empty */
    while (s.Count !=0 && s.Peek() > arr[i]) {
            Console.WriteLine(s.Peek() + " --> " + arr[i]);
            s.Pop();
        }
          
        /* push next to stack so that we can find
        next smaller for it */
        s.Push(arr[i]);
        }
          
        /* After iterating over the loop, the remaining
        elements in stack do not have the next smaller
        element, so print -1 for them */
            while (s.Count!=0) {
        Console.WriteLine(s.Peek() + " --> " + "-1");
        s.Pop();
        }
    }
    /* Driver program to test above functions */
    public static void Main () {
        int []arr = { 11, 13, 21, 3};
        int n = arr.Length;
        printNSE(arr, n);
    }
}
//This code is contributed by PrinciRaj1992
输出:
21 --> 3
13 --> 3
11 --> 3
3 --> -1

时间复杂度: O(n)。最坏的情况发生在所有元素都按升序排序时。如果元素按升序排序,则每个元素最多处理4次。
a)最初被推入堆栈。
b)处理下一个元素时从堆栈中弹出。
c)由于下一个元素较小,因此被推回堆栈。
d)在算法的第3步中从堆栈中弹出。
如何获得与输入顺序相同的元素?
上面的方法可能不会产生与输入相同顺序的输出元素。为了实现相同的顺序,我们可以在C++中使用unordered_map(在Java使用HashMap)。

C++

// A Stack based C++ program to find next
// smaller element for all array elements
// in same order as input.
#include 
using namespace std;
 
/* prints element and NSE pair for all
elements of arr[] of size n */
void printNSE(int arr[], int n)
{
    stack s;
    unordered_map mp;
 
    /* push the first element to stack */
    s.push(arr[0]);
     
 
    // iterate for rest of the elements
    for (int i = 1; i < n; i++) {
 
        if (s.empty()) {
            s.push(arr[i]);
            continue;
        }
 
        /* if stack is not empty, then
       pop an element from stack.
       If the popped element is greater
       than next, then
    a) print the pair
    b) keep popping while elements are
    greater and stack is not empty */
        while (s.empty() == false && s.top() > arr[i]) {
            mp[s.top()] = arr[i];
            s.pop();
        }
 
        /* push next to stack so that we can find
    next smaller for it */
        s.push(arr[i]);
    }
 
    /* After iterating over the loop, the remaining
  elements in stack do not have the next smaller
  element, so print -1 for them */
    while (s.empty() == false) {
         mp[s.top()] = -1;
        s.pop();
    }
 
    for (int i=0; i " << mp[arr[i]] << endl;
}
 
/* Driver program to test above functions */
int main()
{
    int arr[] = { 11, 13, 21, 3 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printNSE(arr, n);
    return 0;
}

Java

// A Stack based Java program to find next
// smaller element for all array elements
// in same order as input.
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG
{
    /* prints element and NSE pair for all
    elements of arr[] of size n */
public static void printNSE(int arr[], int n)
{
    Stack s = new Stack();
    HashMap mp = new HashMap();
         
    /* push the first element to stack */
    s.push(arr[0]);
         
         
    // iterate for rest of the elements
    for (int i = 1; i < n; i++) {
 
        if (s.empty()) {
            s.push(arr[i]);
            continue;
        }
         
         
        /* if stack is not empty, then
    pop an element from stack.
    If the popped element is greater
    than next, then
    a) print the pair
    b) keep popping while elements are
    greater and stack is not empty */
     
    while (s.empty() == false && s.peek() > arr[i]) {
            mp.put(s.peek(), arr[i]);
            s.pop();
        }
         
        /* push next to stack so that we can find
        next smaller for it */
        s.push(arr[i]);
    }
         
         
         
    /* After iterating over the loop, the remaining
    elements in stack do not have the next smaller
    element, so print -1 for them */
    while (s.empty() == false) {
        mp.put(s.peek(), -1);
        s.pop();
    }
     
     
    for (int i=0; i " + mp.get(arr[i]));
}
     
    /* Driver program to test above functions */
    public static void main (String[] args) {
        int arr[] = { 11, 13, 21, 3};
        int n = arr.length;
        printNSE(arr, n);
    }
}

C#

// A Stack based C# program to find next
// smaller element for all array elements
// in same order as input.using System;
using System;
using System.Collections.Generic;
 
class GFG
{
    /* prints element and NSE pair for all
    elements of arr[] of size n */
    public static void printNSE(int []arr, int n)
    {
        Stack s = new Stack();
        Dictionary mp = new Dictionary();
 
        /* push the first element to stack */
        s.Push(arr[0]);
 
 
        // iterate for rest of the elements
        for (int i = 1; i < n; i++)
        {
            if (s.Count==0)
            {
                s.Push(arr[i]);
                continue;
            }
            /* if stack is not empty, then
            pop an element from stack.
            If the popped element is greater
            than next, then
            a) print the pair
            b) keep popping while elements are
            greater and stack is not empty */
            while (s.Count != 0 && s.Peek() > arr[i])
            {
                mp.Add(s.Peek(), arr[i]);
                s.Pop();
            }
 
            /* push next to stack so that we can find
            next smaller for it */
            s.Push(arr[i]);
        }
 
 
 
        /* After iterating over the loop, the remaining
        elements in stack do not have the next smaller
        element, so print -1 for them */
        while (s.Count != 0)
        {
            mp.Add(s.Peek(), -1);
            s.Pop();
        }
 
 
        for (int i = 0; i < n; i++)
        Console.WriteLine(arr[i] + " ---> " + mp[arr[i]]);
    }
     
    // Driver code
    public static void Main()
    {
        int []arr = {11, 13, 21, 3};
        int n = arr.Length;
        printNSE(arr, n);
    }
}
// This code is contributed by
// 29AjayKumar
输出:
11 ---> 3
13 ---> 3
21 ---> 3
3 ---> -1