Open In App

Minimize Value of K for Creating Set of Unique Elements of Size Atleast M

Last Updated : 28 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if set of unique elements
// can be crated for given K = mid or not
bool ispos(int mid, int A[], int N, int M)
{
    // size of set of unique elements
    // formed using K = mid
    int currSizeOfset = 0;
 
    // iterating on array A[] to add elements
    // in the set from A[i] to A[i] + K - 1
    for (int i = 0; i < N - 1; i++) {
 
        // if consecutive elements are less than mid numbers
        // apart only add A[i + 1] - A[i] numbers because
        // some numbers will repeat
        if (A[i + 1] - A[i] <= mid)
            currSizeOfset += A[i + 1] - A[i];
 
        // if they are greater than mid numbers apart all
        // numbers will be contributing in size of set
        else {
            currSizeOfset += mid;
        }
    }
 
    // for last number of A[N] to A[N] + K - 1
    currSizeOfset += mid;
 
    // if size of set is grater than required
    // size then return 1 else return 0
    return currSizeOfset >= M;
}
 
// Function to Minimize the value of K for
// creating set of unique elements  of size at least M
int findMinOp(int A[], int N, int M)
{
 
    // Range of binary search
    int low = 1, high = 1e9;
 
    // Running loop till high
    // is not equal to low
    while (high - low > 1) {
 
        // mid is average of low and high
        int mid = (low + high) / 2;
 
        // Checking test function
        if (ispos(mid, A, N, M)) {
            high = mid;
        }
        else {
            low = mid + 1;
        }
    }
 
    // Checking whether low can be answer
    if (ispos(low, A, N, M))
        return low;
 
    // If not then it is high
    else
        return high;
}
 
// Driver Code
int32_t main()
{
 
    // Input 1
    int N = 2, M = 5;
    int A[] = { 1, 5 };
 
    // Function Call
    cout << findMinOp(A, N, M) << endl;
 
    // Input 2
    int N1 = 3, M1 = 10;
    int A1[] = { 2, 4, 10 };
 
    // Function Call
    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;
        }
    }
 
    // Driver Code
    public static void main(String[] args) {
        // Input 1
        int N = 2;
        int M = 5;
        int[] A = {1, 5};
 
        // Function Call
        System.out.println(findMinOp(A, N, M));
 
        // Input 2
        int N1 = 3;
        int M1 = 10;
        int[] A1 = {2, 4, 10};
 
        // Function Call
        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
 
 
# Driver Code
if __name__ == "__main__":
    # Input 1
    N = 2
    M = 5
    A = [1, 5]
 
    # Function Call
    print(find_min_op(A, N, M))
 
    # Input 2
    N1 = 3
    M1 = 10
    A1 = [2, 4, 10]
 
    # Function Call
    print(find_min_op(A1, N1, M1))


C#




// C# program for the above approach
using System;
 
public class GFG {
    // Function to check if a set of unique elements
    // can be created for a given K = mid or not
    static bool IsPositive(int mid, int[] A, int N, int M)
    {
        // Size of the set of unique elements
        // formed using K = mid
        int currentSizeOfSet = 0;
 
        // Iterating on array A[] to add elements
        // in the set from A[i] to A[i] + K - 1
        for (int i = 0; i < N - 1; i++) {
            // If consecutive elements are less than mid
            // numbers apart, only add A[i + 1] - A[i]
            // numbers because some numbers will repeat
            if (A[i + 1] - A[i] <= mid)
                currentSizeOfSet += A[i + 1] - A[i];
            // If they are greater than mid numbers apart,
            // all numbers will be contributing to the size
            // of the set
            else {
                currentSizeOfSet += mid;
            }
        }
 
        // For the last number of A[N] to A[N] + K - 1
        currentSizeOfSet += mid;
 
        // If the size of the set is greater than or equal
        // to the required size then return true, else
        // return false
        return currentSizeOfSet >= M;
    }
 
    // Function to minimize the value of K for
    // creating a set of unique elements of size at least M
    static int FindMinOp(int[] A, int N, int M)
    {
        // Range of binary search
        int low = 1, high = 1000000000;
 
        // Running the loop until high is not equal to low
        while (high - low > 1) {
            // Mid is the average of low and high
            int mid = (low + high) / 2;
 
            // Checking the test function
            if (IsPositive(mid, A, N, M)) {
                high = mid;
            }
            else {
                low = mid + 1;
            }
        }
 
        // Checking whether low can be the answer
        if (IsPositive(low, A, N, M))
            return low;
 
        // If not, then it is high
        else
            return high;
    }
 
    // Driver Code
    static void Main()
    {
        // Input 1
        int N = 2, M = 5;
        int[] A = { 1, 5 };
 
        // Function Call
        Console.WriteLine(FindMinOp(A, N, M));
 
        // Input 2
        int N1 = 3, M1 = 10;
        int[] A1 = { 2, 4, 10 };
 
        // Function Call
        Console.WriteLine(FindMinOp(A1, N1, M1));
    }
}
 
// This code is contributed by Susobhan Akhuli


Javascript




// Javascript Implementation
 
// Function to check if set of unique elements
// can be created for given K = mid or not
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 to Minimize the value of K for
// creating set of unique elements of size at least 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;
    }
}
 
// Driver Code
 
// Input 1
const N = 2, M = 5;
const A = [1, 5];
console.log(findMinOp(A, N, M));
 
// Input 2
const N1 = 3, M1 = 10;
const A1 = [2, 4, 10];
console.log(findMinOp(A1, N1, M1));
 
 
 
// This code is contributed by Tapesh(tapeshdua420)


Output

3
4





Time Complexity: O(N*log N)
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads