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

📅  最后修改于: 2021-05-17 22:35:51             🧑  作者: 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)