📌  相关文章
📜  使数组递减所需的最小步骤

📅  最后修改于: 2021-09-05 08:37:02             🧑  作者: Mango

给定一个数组arr[] ,任务是找到使数组减少所需的最小步骤,其中在每个步骤中删除所有大于其左侧元素的元素。

例子:

朴素的方法:迭代数组并计算大于其左侧的元素,如果元素不大于其左侧,则将元素推入另一个数组(例如arr1 ),并在数组完成迭代后复制所有元素arr1 到初始数组并重复相同的过程,直到在一个步骤中删除的元素数为 0。这种方法在最坏的情况下需要 O(N 2 ) 时间和 O(N) 空间。

有效的方法:这个想法是使用堆栈,只有当元素大于其前一个元素时才将元素推入堆栈,否则计算扫描和弹出的次数。
我们只关心较小的元素。

CPP
//C++ implementation to make an 
// array decreasing
  
#include
using namespace std;
  
// Structure to store elements
struct Node 
{
    int elementID;
    int stepsToeliminate;
};
  
// Function to find the 
// minimum steps required
void minSteps(int arr[], int N)
{
    stack s;
      
    s.push({ 0, -1 });
      
    // Minimum steps
    int maxStepsToeliminate = -1; 
      
    // Loop to iterate 
    // over the array
    for (int i = 1; i < N; i++)
    {
        int stepsToeliminate = 1;
          
        // Traversing the stack until
        // it is not empty
        while (!s.empty())
        {
            // Condition if the top of the
            // stack is greater than the 
            // current element
            if (arr[s.top().elementID] >= 
                                   arr[i])
            {
                stepsToeliminate = max(stepsToeliminate, 
                           s.top().stepsToeliminate + 1);
                s.pop();
            }
            else
            {
                break;
            }
        }
          
        // Condition if no previous
        // elements value less than
        // this element then steps is -1
        if (s.empty())
        {
            stepsToeliminate = -1;
        }
      
        maxStepsToeliminate = max(
            maxStepsToeliminate, stepsToeliminate
            );
        s.push({ i, stepsToeliminate });
    }
      
    cout << (maxStepsToeliminate < 0 ? 0 :
              maxStepsToeliminate) << endl;
}
  
// Driver Code
int main()
{
    int arr[] = {3, 2, 1, 7, 5};
      
    int size = sizeof(arr)/sizeof(arr[0]);
      
    minSteps(arr, size);
      
    return 0;
}


Java
// Java implementation to make an 
// array decreasing
import java.util.*;
  
class GFG{
   
// Structure to store elements
static class Node 
{
    int elementID;
    int stepsToeliminate;
    public Node(int elementID, int stepsToeliminate) {
        super();
        this.elementID = elementID;
        this.stepsToeliminate = stepsToeliminate;
    }
      
};
   
// Function to find the 
// minimum steps required
static void minSteps(int arr[], int N)
{
    Stack s = new Stack();
       
    s.add(new Node( 0, -1 ));
       
    // Minimum steps
    int maxStepsToeliminate = -1; 
       
    // Loop to iterate 
    // over the array
    for (int i = 1; i < N; i++)
    {
        int stepsToeliminate = 1;
           
        // Traversing the stack until
        // it is not empty
        while (!s.isEmpty())
        {
            // Condition if the top of the
            // stack is greater than the 
            // current element
            if (arr[s.peek().elementID] >= 
                                   arr[i])
            {
                stepsToeliminate = Math.max(stepsToeliminate, 
                           s.peek().stepsToeliminate + 1);
                s.pop();
            }
            else
            {
                break;
            }
        }
           
        // Condition if no previous
        // elements value less than
        // this element then steps is -1
        if (s.isEmpty())
        {
            stepsToeliminate = -1;
        }
       
        maxStepsToeliminate = Math.max(
            maxStepsToeliminate, stepsToeliminate
            );
        s.add(new Node(i, stepsToeliminate ));
    }
       
    System.out.print((maxStepsToeliminate < 0 ? 0 :
              maxStepsToeliminate) +"\n");
}
   
// Driver Code
public static void main(String[] args)
{
    int arr[] = {3, 2, 1, 7, 5};
       
    int size = arr.length;
       
    minSteps(arr, size);     
}
} 
  
// This code is contributed by sapnasingh4991


Python3
# Python3 implementation to make an 
# array decreasing 
  
# Function to find the 
# minimum steps required 
def minSteps(arr,  N) : 
  
    s = []; 
      
    s.append(( 0, -1 )); 
      
    # Minimum steps 
    maxStepsToeliminate = -1; 
      
    # Loop to iterate 
    # over the array 
    for i in range(1, N) :
      
        stepsToeliminate = 1; 
          
        # Traversing the stack until 
        # it is not empty 
        while (len(s) != 0) : 
  
            # Condition if the top of the 
            # stack is greater than the 
            # current element 
            if (arr[s[-1][0]] >= arr[i]) :
                stepsToeliminate = max(stepsToeliminate, s[-1][1] + 1);
                s.pop(); 
          
            else :
              
                break; 
      
        # Condition if no previous 
        # elements value less than 
        # this element then steps is -1 
        if (len(s) == 0) : 
          
            stepsToeliminate = -1; 
      
      
        maxStepsToeliminate = max( maxStepsToeliminate, stepsToeliminate ); 
          
        s.append(( i, stepsToeliminate )); 
      
    print(  0 if (maxStepsToeliminate < 0 ) else  maxStepsToeliminate ); 
  
  
# Driver Code 
if __name__ == "__main__" : 
  
    arr = [3, 2, 1, 7, 5]; 
      
    size = len(arr); 
      
    minSteps(arr, size); 
      
# This code is contributed by AnkitRai01


C#
// C# implementation to make an 
// array decreasing
using System;
using System.Collections.Generic;
  
class GFG{
    
// Structure to store elements
class Node 
{
    public int elementID;
    public int stepsToeliminate;
    public Node(int elementID, int stepsToeliminate) {
        this.elementID = elementID;
        this.stepsToeliminate = stepsToeliminate;
    }
       
};
    
// Function to find the 
// minimum steps required
static void minSteps(int []arr, int N)
{
    Stack s = new Stack();
        
    s.Push(new Node( 0, -1 ));
        
    // Minimum steps
    int maxStepsToeliminate = -1; 
        
    // Loop to iterate 
    // over the array
    for (int i = 1; i < N; i++)
    {
        int stepsToeliminate = 1;
            
        // Traversing the stack until
        // it is not empty
        while (s.Count!=0)
        {
            // Condition if the top of the
            // stack is greater than the 
            // current element
            if (arr[s.Peek().elementID] >= 
                                   arr[i])
            {
                stepsToeliminate = Math.Max(stepsToeliminate, 
                           s.Peek().stepsToeliminate + 1);
                s.Pop();
            }
            else
            {
                break;
            }
        }
            
        // Condition if no previous
        // elements value less than
        // this element then steps is -1
        if (s.Count!=0)
        {
            stepsToeliminate = -1;
        }
        
        maxStepsToeliminate = Math.Max(
            maxStepsToeliminate, stepsToeliminate
            );
        s.Push(new Node(i, stepsToeliminate ));
    }
        
    Console.Write((maxStepsToeliminate < 0 ? 0 :
              maxStepsToeliminate) +"\n");
}
    
// Driver Code
public static void Main(String[] args)
{
    int []arr = {3, 2, 1, 7, 5};
        
    int size = arr.Length;
        
    minSteps(arr, size);     
}
}
   
// This code is contributed by PrinciRaj1992


输出:
2

性能分析:

  • 时间复杂度:与上述方法一样,有一个循环需要 O(N) 时间,因此时间复杂度将为O(N)
  • 空间复杂度:在上面的方法中,有一个堆栈用来存储前面的元素,因此空间复杂度为O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live