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++ 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;
} |
import java.util.*;
public class Main
{ // Function to count the number of increasing
// subsequences that can be deleted to empty the array
static int findMinOp( int [] A, int N)
{
// Declaring priority queue
PriorityQueue<Integer> pq = new PriorityQueue<>();
// Iterating from 0 to N
for ( int i = 0 ; i < N; i++)
{
// Insert current element in priority queue
pq.offer(A[i]);
// Get an iterator pointing to the same element in
// the priority queue
Iterator<Integer> it = pq.iterator();
int prev = Integer.MIN_VALUE;
// Find the previous element in the priority queue
while (it.hasNext()) {
int curr = it.next();
if (curr == A[i]) {
break ;
}
prev = curr;
}
// If it is the first element in the sorted
// priority queue, skip the current iteration
if (A[i] == prev) {
continue ;
}
// Delete that previous element from the priority queue
pq.remove(prev);
}
// Return the final answer which is the size of the priority queue
return pq.size();
}
// Driver code
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));
}
} // This code is contributed by Prajwal Kandekar |
# Python code to implement the approach import heapq
# Function to count number of increasing # subsequences that can be deleted # to empty array def findMinOp(A, N):
# Declaring priority queue
pq = []
# Iterating from 0 to N
for i in range (N):
# Insert current element
# in priority queue
heapq.heappush(pq, A[i])
# If it is first element in
# sorted pq skip the current
# iteration
if pq.index(A[i]) = = 0 :
continue
# Delete that previous
# element from pq
pq.remove(A[i - 1 ])
# Return final answer which is
# size of priority queue
return len (pq)
# Driver Code if __name__ = = '__main__' :
A = [ 2 , 1 , 4 , 5 , 3 ]
N = len (A)
# Function Call
print (findMinOp(A, N))
|
// C# code to implement the approach using System;
using System.Collections.Generic;
class GFG
{ static int FindMinOp( int [] A, int N)
{
// Create a stack to track increasing subsequences
Stack< int > stack = new Stack< int >();
for ( int i = 0; i < N; i++)
{
// If the stack is empty or the current element is greater than the top of the stack,
// push the current element onto the stack
if (stack.Count == 0 || A[i] > stack.Peek())
{
stack.Push(A[i]);
}
else
{
// If the current element is smaller than or equal
// to the top of the stack,
// pop elements from the stack until a
// suitable position is found
while (stack.Count > 0 && A[i] < stack.Peek())
{
stack.Pop();
}
// Push the current element onto the stack
stack.Push(A[i]);
}
}
// The size of the stack represents the minimum number
// of increasing subsequences
// that can be deleted to empty the array
return stack.Count;
}
static void Main()
{
// Example usage
int [] A = { 2, 1, 4, 5, 3 };
int N = A.Length;
// Function Call
Console.WriteLine(FindMinOp(A, N));
}
} |
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)); |
2
Time Complexity: O(NlogN)
Auxiliary Space: O(N)
Related Articles :