Find the minimum value of K required to remove all elements from the array in at most M operations
Last Updated :
14 Feb, 2024
Given array A[] of size N and integer M, Perform the following operation until the array becomes empty. Choose K and the pick first K elements of array A[]. In one operation subtract all these chosen K elements by 1 if any element becomes zero that element will be deleted and it will be replaced by K + 1’th element of the array. The task for this problem is to find the minimum value of K to remove all elements of an array in at most M operations.
Examples:
Input: A[] = {4, 7, 8, 6, 4}, M = 8
Output: 4
Explanation: Chose K = 4 initially we have first four elements of array S = [4, 7, 8, 6]
- In the first operation subtract 1 from chosen set S, and it becomes [3, 6, 7, 5]
- In the second operation subtract 1 from the chosen set S, and it becomes [2, 5, 6, 4]
- In the third operation subtract 1 from chosen set S, and it becomes [1, 4, 5, 3]
- In the fourth operation subtract 1 from the chosen set S, and it becomes [0, 3, 4, 2] since one of the elements becomes zero it will be replaced by the next element which is 4 new S is [3, 4, 2, 4].
- In the fifth operation subtract 1 from chosen set S, and it becomes [2, 3, 1, 3]
- In the Sixth operation subtract 1 from chosen set S, and it becomes [1, 2, 0, 2] since one of the elements becomes zero since there is no other element left it will be removed new S becomes [1, 2, 2]
- In the seventh operation subtract 1 from the chosen set S, and it becomes [0, 1, 1] since one of the elements becomes zero since there is no other element left it will be removed new S becomes [1, 1]
- In the eighth operation subtract 1 from the chosen set S, and it becomes [0, 0] since all element becomes zero remove them all.
In 8 operations all elements of the array are deleted which is less than equal to the number of allowed operations.
Input: A[] = {3, 5, 2, 8, 7, 4}, M = 11
Output: 3
Explanation: Chose K= 3 initially we have the first three elements of array S = [3, 5, 2]
- In the first operation subtract 1 from the chosen set S, and it becomes [2, 4, 1]
- In the second operation subtract 1 from the chosen set S, and it becomes [1, 3, 0] Since onthat element with the next element of the array S becomes [1, 3, 8]
- In the third operation subtract 1 from the chosen set S, and it becomes [0, 2, 7] Since one of the elements becomes zero replace that element with the next element of the array S becomes [2, 7, 7]
- In fourth operation subtract 1 from chosen set S, it becomes [1, 6, 6]
- In fifth operation subtract 1 from chosen set S, it becomes [0, 5, 5] since one of the elements becomes zero replace that element with next element of array S becomes [5, 5, 4]
- In sixth operation subtract 1 from chosen set S, it becomes [4, 4, 3]
- In seventh operation subtract 1 from chosen set S, it becomes [3, 3, 2]
- In eighth operation subtract 1 from chosen set S, it becomes [2, 2, 1]
- In ninth operation subtract 1 from chosen set S, it becomes [1, 1, 0] since one of the elements becomes zero since there is no other element left it will be simply removed new S becomes [1, 1]
- In tenth operation subtract 1 from chosen set S, it becomes [0, 0] since all elements becomes zero remove them all.
In 10 operations all elements of array are deleted which are less than equal to number of allowed operations.
Minimum value of K to remove all elements from array in at most M operations Using Binary Search:
Binary Search can be used to solve this problem and the range of binary search will be 1 to M. f(K) is monotonic function that represents whether all elements from array can be removed in at most M operations with by selecting K. it is of the form FFFFFFFTTTTTTT. we have to find when the first time function becomes true using Binary Search.
We will use multiset to check if all the elements can be removed in at most M operations. we will maintain variable currentOperations and maxOperations .
A[] = {4, 7, 8, 6, 4}, N = 5
since we cannot just take first K = 4 elements and perform operations of subtraction one by one we will do the following.
For K = 4 we will have multiset MS[] = {4, 6, 7, 8} initially, smallest number will be number of operations we need to perform to make the smallest element zero as told delete that element and insert next element. But rather than subtracting each element of multiset by 4 we will maintain another variable currentOperations which will make sure the relative ordering of incoming elements. After deleting 4 increase the currentOperations by 4 and incoming element is A[5] = 4 will be added with currentOperations = 4 then inserted in multiset MS[] becomes {6, 7, 8, 8}. each element of multiset is actually a Acutal[] = MS[] – {currentOperations} = {6 – 4, 7 – 4, 8 – 4, 8 – 4} = {2, 3, 4, 4}
In 4 operations whole multiset can be made empty. currentOperations = 4 increased by 4
So for K = 4 in 8 operations whole array A[] can be made empty by performing operations given in above problem.
Below are the steps for the above approach:
- Set low and high range of binary search.
- ispos(K) function is used to check whether elements from array can be removed in at most M operations with K.
- Run while loop till high and low are not equal.
- In while loop find middle element and store it in mid variable.
- Check if that K = mid is enough to remove all elements from array in at most M operations using ispos() function. If it is true then set high = mid else low = mid + 1.
- After loop ends if ispos() true for low then return low else check if it is true for high then return high else return -1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool ispos( int K, int A[], int N, int M)
{
int currentNumberOfOperations = 0;
int maximumNumberOfOperations = 0;
multiset< int > ms;
for ( int i = 0; i < K; i++)
ms.insert(A[i]);
for ( int i = K; i < N; i++) {
int first = *ms.begin() - currentNumberOfOperations;
ms.erase(ms.begin());
currentNumberOfOperations += first;
ms.insert(A[i] + currentNumberOfOperations);
maximumNumberOfOperations
= max(maximumNumberOfOperations, *(--ms.end()));
}
return maximumNumberOfOperations <= M;
}
int findMinM( int A[], int N, int M)
{
int low = 1, high = M;
while (high - low > 1) {
int mid = (low + high) / 2;
if (ispos(mid, A, N, M)) {
high = mid;
}
else {
low = mid + 1;
}
}
if (ispos(low, A, N, M))
return low;
else if (ispos(high, A, N, M))
return high;
return -1;
}
int32_t main()
{
int N = 5, M = 8;
int A[] = { 4, 7, 8, 6, 4 };
cout << findMinM(A, N, M) << endl;
return 0;
}
|
Java
import java.util.Arrays;
import java.util.TreeSet;
class GFG {
static boolean isPos( int K, int [] A, int N, int M)
{
int currentNumberOfOperations = 0 ;
int maximumNumberOfOperations = 0 ;
TreeSet<Integer> treeSet = new TreeSet<>();
for ( int i = 0 ; i < K; i++)
treeSet.add(A[i]);
for ( int i = K; i < N; i++) {
int first = treeSet.first()
- currentNumberOfOperations;
treeSet.remove(treeSet.first());
currentNumberOfOperations += first;
treeSet.add(A[i] + currentNumberOfOperations);
maximumNumberOfOperations = Math.max(
maximumNumberOfOperations, treeSet.last());
}
return maximumNumberOfOperations <= M;
}
static int findMinM( int [] A, int N, int M)
{
int low = 1 , high = M;
while (high - low > 1 ) {
int mid = (low + high) / 2 ;
if (isPos(mid, A, N, M)) {
high = mid;
}
else {
low = mid + 1 ;
}
}
if (isPos(low, A, N, M))
return low;
else if (isPos(high, A, N, M))
return high;
return - 1 ;
}
public static void main(String[] args)
{
int N = 5 , M = 8 ;
int [] A = { 4 , 7 , 8 , 6 , 4 };
System.out.println(findMinM(A, N, M));
}
}
|
Python3
from sortedcontainers import SortedList
def is_pos(K, A, N, M):
current_number_of_operations = 0
maximum_number_of_operations = 0
sl = SortedList()
for i in range (K):
sl.add(A[i])
for i in range (K, N):
first = sl[ 0 ] - current_number_of_operations
sl.discard(sl[ 0 ])
current_number_of_operations + = first
sl.add(A[i] + current_number_of_operations)
maximum_number_of_operations = max (
maximum_number_of_operations, sl[ - 1 ])
return maximum_number_of_operations < = M
def find_min_M(A, N, M):
low, high = 1 , M
while high - low > 1 :
mid = (low + high) / / 2
if is_pos(mid, A, N, M):
high = mid
else :
low = mid + 1
if is_pos(low, A, N, M):
return low
elif is_pos(high, A, N, M):
return high
return - 1
if __name__ = = "__main__" :
N, M = 5 , 8
A = [ 4 , 7 , 8 , 6 , 4 ]
print (find_min_M(A, N, M))
|
C#
using System;
using System.Collections.Generic;
class Program
{
static bool IsPos( int K, int [] A, int N, int M)
{
int currentNumberOfOperations = 0;
int maximumNumberOfOperations = 0;
var ms = new SortedSet< int >();
for ( int i = 0; i < K; i++)
ms.Add(A[i]);
for ( int i = K; i < N; i++)
{
int first = ms.Min - currentNumberOfOperations;
ms.Remove(ms.Min);
currentNumberOfOperations += first;
ms.Add(A[i] + currentNumberOfOperations);
maximumNumberOfOperations = Math.Max(maximumNumberOfOperations, ms.Max);
}
return maximumNumberOfOperations <= M;
}
static int FindMinM( int [] A, int N, int M)
{
int low = 1, high = M;
while (high - low > 1)
{
int mid = (low + high) / 2;
if (IsPos(mid, A, N, M))
{
high = mid;
}
else
{
low = mid + 1;
}
}
if (IsPos(low, A, N, M))
return low;
else if (IsPos(high, A, N, M))
return high;
return -1;
}
static void Main()
{
int N = 5, M = 8;
int [] A = { 4, 7, 8, 6, 4 };
Console.WriteLine(FindMinM(A, N, M));
}
}
|
Javascript
function ispos(K, A, N, M) {
let currentNumberOfOperations = 0;
let maximumNumberOfOperations = 0;
let ms = new Set();
for (let i = 0; i < K; i++)
ms.add(A[i]);
for (let i = K; i < N; i++) {
let first = Math.min(...ms) - currentNumberOfOperations;
ms. delete (Math.min(...ms));
currentNumberOfOperations += first;
ms.add(A[i] + currentNumberOfOperations);
maximumNumberOfOperations = Math.max(maximumNumberOfOperations, Math.max(...ms));
}
return maximumNumberOfOperations <= M;
}
function findMinM(A, N, M) {
let low = 1, high = M;
while (high - low > 1) {
let mid = Math.floor((low + high) / 2);
if (ispos(mid, A, N, M)) {
high = mid;
} else {
low = mid + 1;
}
}
if (ispos(low, A, N, M))
return low;
else if (ispos(high, A, N, M))
return high;
return -1;
}
let N = 5, M = 8;
let A = [4, 7, 8, 6, 4];
console.log(findMinM(A, N, M));
|
Complexity Analysis:
Time Complexity: O(N * logN * log(R – L)), NlogN time complexity of ispos() function and other log(R – L) is number of checks made by binary search in given binary search range L to R
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...