Minimum steps required to make an array decreasing

Given an array arr[], the task is to find the minimum steps required to make an array decreasing, where in each step remove all elements which are greater than elements on its left element.

Examples:

Input: arr[] = {3, 2, 1, 7, 5}
Output: 2
Explanation:
In the above array there are two steps required to make array decreasing –
Step 1: In step 1 there is one element which is greater than its left, that is 7 > 1.
Step 2: In step 2 there is one element which is greater than its left, that is 5 > 1.

Input: arr[] = {6, 5, 8, 4, 7, 10, 9}
Output: 2
In the above array there are two steps required to make array decreasing –
Step 1: In step 1 there are three elements which is greater than its left, which is 8 > 5, 7 > 4 and 10 > 7.
Step 2: In step 2 there are three is only one element which is greater than its left which is 9 > 4.

Naive Approach: Iterate over the array and count the elements which are greater than its left, if the element is not greater than its left then push the element into another array (say arr1) and after the complete iteration of the array copy all the elements of arr1 to the initial array and repeat the same procedure until the count of elements removed in a step is 0. This approach takes O(N2) time in the worst case and O(N) space.



Efficient Approach: The idea is to use a stack and push the element into the stack only if the element is greater than its previous element, else count the number of scans and pop.
We only care about the elements which is smaller.

CPP

filter_none

edit
close

play_arrow

link
brightness_4
code

//C++ implementation to make an 
// array decreasing
  
#include<bits/stdc++.h>
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<Node> 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;

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<Node> s = new Stack<Node>();
       
    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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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 )); 
      
    print0 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<Node> s = new Stack<Node>();
        
    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

chevron_right


Output:

2

Performance Analysis:

  • Time Complexity: As in the above approach, there is one loop which takes O(N) time, Hence the Time Complexity will be O(N).
  • Space Complexity: As in the above approach, there is stack used to store the previous elements, Hence the space complexity will be O(N).

Don’t stop now and take your learning to the next level. Learn all the important concepts of Data Structures and Algorithms with the help of the most trusted course: DSA Self Paced. Become industry ready at a student-friendly price.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.