Minimize Value of K for Creating Set of Unique Elements of Size Atleast M
Last Updated :
28 Jan, 2024
Given array A[] of size N and integer M, array A[] is strictly increasing (A[1] < A[2] < ….. < A[N]). Create set of unique elements of size at least M. To create set choose K and insert all numbers from A[i] to A[i] + K – 1 for all 1 <= i <= N. The task is to minimize the value of such K.
Examples:
Input: A[] = {1, 5}, M = 5
Output: 3
Explanation: if K = 3
- for i = 1, Inserting all numbers from A[1] to A[1] + K – 1, i.e. from 1 to 3 to form set {1, 2, 3}
- for i = 2, inserting all numbers from A[2] to A[2] + K – 1 i.e. from 5 to 7 to form set {1, 2, 3, 5, 6, 7}
final set is {1, 2, 3, 5, 6, 7} whose size is at least M satisfies the conditions
Input: A[] = {2, 4, 10}, M = 10
Output: 4
Explanation: if K = 4
- for i = 1, inserting all numbers from A[1] to A[1] + K – 1, i.e. from 2 to 5 to form set {2, 3, 4, 5}
- for i = 2, inserting all numbers from A[2] to A[2] + K – 1, i.e. from 4 to 7 to form set {2, 3, 4, 5, 6, 7}
- for i = 3, inserting all numbers from A[3] to A[3] + K – 1, i.e. from 10 to 13 to form set {2, 3, 4, 5, 6, 7, 10, 11, 12, 13}
final set {2, 3, 4, 5, 6, 7, 10, 11, 12, 13} whose size is at least M satisfies the conditions
Approach: To solve the problem follow the below idea:
Binary Search can be used to solve this problem and the range of binary search will be 1 to 1e9. f(K) is monotonic function represents whether chosen K will generate set of unique elements of size at least M. it is of the form FFFFFFFFTTTTTTT. we have to find when the first time function becomes true using Binary Search.
Below are the steps for the above approach:
- Set low and high range of binary serach.
- ispos(mid) function used to check whether mid can generate set of unique elements of size at least M.
- 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 mid can generate set of unique elements of size at least M using ispos() function.
- If it is true then set high = mid,
- else low = mid + 1.
- After loop ends if ispos() true for high then return high else return low.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool ispos( int mid, int A[], int N, int M)
{
int currSizeOfset = 0;
for ( int i = 0; i < N - 1; i++) {
if (A[i + 1] - A[i] <= mid)
currSizeOfset += A[i + 1] - A[i];
else {
currSizeOfset += mid;
}
}
currSizeOfset += mid;
return currSizeOfset >= M;
}
int findMinOp( int A[], int N, int M)
{
int low = 1, high = 1e9;
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
return high;
}
int32_t main()
{
int N = 2, M = 5;
int A[] = { 1, 5 };
cout << findMinOp(A, N, M) << endl;
int N1 = 3, M1 = 10;
int A1[] = { 2, 4, 10 };
cout << findMinOp(A1, N1, M1) << endl;
return 0;
}
|
Java
public class MinOperations {
static boolean isPos( int mid, int [] A, int N, int M) {
int currSizeOfSet = 0 ;
for ( int i = 0 ; i < N - 1 ; i++) {
if (A[i + 1 ] - A[i] <= mid) {
currSizeOfSet += A[i + 1 ] - A[i];
} else {
currSizeOfSet += mid;
}
}
currSizeOfSet += mid;
return currSizeOfSet >= M;
}
static int findMinOp( int [] A, int N, int M) {
int low = 1 , high = 1000000000 ;
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 {
return high;
}
}
public static void main(String[] args) {
int N = 2 ;
int M = 5 ;
int [] A = { 1 , 5 };
System.out.println(findMinOp(A, N, M));
int N1 = 3 ;
int M1 = 10 ;
int [] A1 = { 2 , 4 , 10 };
System.out.println(findMinOp(A1, N1, M1));
}
}
|
Python3
def is_pos(mid, A, N, M):
curr_size_of_set = 0
for i in range (N - 1 ):
if A[i + 1 ] - A[i] < = mid:
curr_size_of_set + = A[i + 1 ] - A[i]
else :
curr_size_of_set + = mid
curr_size_of_set + = mid
return curr_size_of_set > = M
def find_min_op(A, N, M):
low, high = 1 , 10 * * 9
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
else :
return high
if __name__ = = "__main__" :
N = 2
M = 5
A = [ 1 , 5 ]
print (find_min_op(A, N, M))
N1 = 3
M1 = 10
A1 = [ 2 , 4 , 10 ]
print (find_min_op(A1, N1, M1))
|
C#
using System;
public class GFG {
static bool IsPositive( int mid, int [] A, int N, int M)
{
int currentSizeOfSet = 0;
for ( int i = 0; i < N - 1; i++) {
if (A[i + 1] - A[i] <= mid)
currentSizeOfSet += A[i + 1] - A[i];
else {
currentSizeOfSet += mid;
}
}
currentSizeOfSet += mid;
return currentSizeOfSet >= M;
}
static int FindMinOp( int [] A, int N, int M)
{
int low = 1, high = 1000000000;
while (high - low > 1) {
int mid = (low + high) / 2;
if (IsPositive(mid, A, N, M)) {
high = mid;
}
else {
low = mid + 1;
}
}
if (IsPositive(low, A, N, M))
return low;
else
return high;
}
static void Main()
{
int N = 2, M = 5;
int [] A = { 1, 5 };
Console.WriteLine(FindMinOp(A, N, M));
int N1 = 3, M1 = 10;
int [] A1 = { 2, 4, 10 };
Console.WriteLine(FindMinOp(A1, N1, M1));
}
}
|
Javascript
function isPos(mid, A, N, M) {
let currSizeOfSet = 0;
for (let i = 0; i < N - 1; i++) {
if (A[i + 1] - A[i] <= mid) {
currSizeOfSet += A[i + 1] - A[i];
} else {
currSizeOfSet += mid;
}
}
currSizeOfSet += mid;
return currSizeOfSet >= M;
}
function findMinOp(A, N, M) {
let low = 1, high = 1e9;
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 {
return high;
}
}
const N = 2, M = 5;
const A = [1, 5];
console.log(findMinOp(A, N, M));
const N1 = 3, M1 = 10;
const A1 = [2, 4, 10];
console.log(findMinOp(A1, N1, M1));
|
Time Complexity: O(N*log N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...