Open In App

Min operations to empty an array by erasing any increasing subsequence

Last Updated : 05 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given array A[] of size N, the task is to find the number of operations to empty the array by performing the following operation one or more times. In one operation choose any strictly increasing subsequence and delete it from A[].

Examples:

Input: A[] = {2, 1, 4, 5, 3}
Output: 2
Explanation: Following operations are performed to empty the array:

  • Choosing increasing subsequence {2, 4, 5} and removing it from A[], A[] becomes {1, 3}
  • Choosing increasing subsequence {1, 3} and removing it from A[], A[] becomes empty.

Input: A[] = {0, 0, 0, 0}
Output:  4

Approach: The idea is to use a Priority Queue data structure to solve this problem.

Iterate over the array and keep inserting new element to priority queue, if given element is inserted at non-starting position than delete element just previous to that position.

Below are the steps for the above approach:

  • Create priority queue pq[] using a multiset container to store the array elements in sorted order.
  • Iterate from 0 to N - 1.
    • For each iteration, insert the current element in pq[].
    • For each iteration, search the current element in pq[].
  • If the current element is at the initial position in the priority queue, move to the next iteration, else erase the previous element in the priority queue.
  • Return the size of pq[] which will be the answer. 

Below is the code for the above approach:

C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;

// Function to count number of increasing
// subsequences that can be deleted
// to empty array
int findMinOp(int A[], int N)
{

    // Declaring priority queue
    multiset<int> pq;

    // Iterating from 0 to N
    for (int i = 0; i < N; i++) {

        // Insert current element
        // in priority queue
        pq.insert(A[i]);

        // Binary search same element
        // in priority queue
        auto it = pq.find(A[i]);

        // If it is first element in
        // sorted pq skip the current
        // iteration
        if (it == pq.begin())
            continue;

        it--;

        // Delete that previous
        // element from pq
        pq.erase(it);
    }

    // Return final answer which is
    // size of priority queue
    return pq.size();
}

// Driver Code
int main()
{
    int A[] = {2, 1, 4, 5, 3 };
    int N = sizeof(A) / sizeof(A[0]);

    // Function Call
    cout << findMinOp(A, N) << endl;

    return 0;
}
Java
import java.util.*;

public class Main {
    public static int findMinOp(int[] A, int N)
    {
        // Declaring priority queue (multiset equivalent in
        // Java)
        TreeMap<Integer, Integer> pq = new TreeMap<>();

        // Iterating from 0 to N
        for (int i = 0; i < N; i++) {
            // Insert current element in priority queue
            pq.put(A[i], pq.getOrDefault(A[i], 0) + 1);

            // Find the element in the priority queue
            Map.Entry<Integer, Integer> it
                = pq.lowerEntry(A[i]);

            // If it is the first element in sorted pq, skip
            // the current iteration
            if (it == null) {
                continue;
            }

            // Delete that previous element from pq
            if (it.getValue() == 1) {
                pq.remove(it.getKey());
            }
            else {
                pq.put(it.getKey(), it.getValue() - 1);
            }
        }

        // Return final answer which is size of priority
        // queue
        int size = 0;
        for (int value : pq.values()) {
            size += value;
        }
        return size;
    }

    public static void main(String[] args)
    {
        int[] A = { 2, 1, 4, 5, 3};
        int N = A.length;

        // Function Call
        System.out.println(findMinOp(A, N));
    }
}
Python
def find_min_op(A, N):
    # Declaring priority queue (multiset equivalent in Python)
    from sortedcontainers import SortedList

    pq = SortedList()

    # Iterating from 0 to N
    for i in range(N):
        # Insert current element in priority queue
        pq.add(A[i])

        # Binary search same element in priority queue
        idx = pq.index(A[i])

        # If it is the first element in sorted pq, skip the current iteration
        if idx == 0:
            continue

        # Delete that previous element from pq
        pq.pop(idx - 1)

    # Return final answer which is size of priority queue
    return len(pq)


# Driver Code
A = [2, 1, 4, 5, 3]
N = len(A)

# Function Call
print(find_min_op(A, N))
C#
using System;
using System.Collections.Generic;

public class Program {
    public static int FindMinOp(int[] A, int N)
    {
        // Declaring a SortedDictionary to act as a multiset
        SortedDictionary<int, int> pq
            = new SortedDictionary<int, int>();

        // Iterating from 0 to N
        for (int i = 0; i < N; i++) {
            // Insert current element in priority queue
            if (pq.ContainsKey(A[i])) {
                pq[A[i]]++;
            }
            else {
                pq[A[i]] = 1;
            }

            // Find the element in the priority queue less
            // than the current element
            int keyToRemove = -1;
            foreach(var key in pq.Keys)
            {
                if (key < A[i]) {
                    keyToRemove = key;
                }
                else {
                    break;
                }
            }

            // If found, remove it
            if (keyToRemove != -1) {
                if (pq[keyToRemove] == 1) {
                    pq.Remove(keyToRemove);
                }
                else {
                    pq[keyToRemove]--;
                }
            }
        }

        // Return final answer which is size of priority
        // queue
        int size = 0;
        foreach(var value in pq.Values) { size += value; }
        return size;
    }

    public static void Main()
    {
        int[] A = { 2, 1, 4, 5, 3};
        int N = A.Length;

        // Function Call
        Console.WriteLine(FindMinOp(A, N));
    }
}
JavaScript
function findMinOp(A, N) {
  // Declaring priority queue
  let pq = [];

  // Iterating from 0 to N
  for (let i = 0; i < N; i++) {
  
    // Insert current element in priority queue
    pq.push(A[i]);
    
    // Convert array to min heap using a comparator function
    pq.sort((a, b) => a - b);

    // If it is the first element in the sorted
    // priority queue, skip the current iteration
    if (pq.indexOf(A[i]) === 0) {
      continue;
    }

    // Delete that previous element from the priority queue
    pq.splice(pq.indexOf(A[i - 1]), 1);
  }

  // Return the final answer which is the size of the priority queue
  return pq.length;
}

// Driver code
let A = [2, 1, 4, 5, 3];
let N = A.length;

// Function call
console.log(findMinOp(A, N));

Output
2

Time Complexity: O(NlogN)
Auxiliary Space: O(N)

Related Articles :


Next Article
Practice Tags :

Similar Reads