Open In App

Find the maximum value of the K-th smallest usage value in Array

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N and with integers M, K. You are allowed to perform an operation where you can increase the value of the least element of the array by 1. You are to do this M times. The task is to find the largest possible value for the Kth smallest value among arr[] after M operations.

Examples

Input: M=10, K=4, arr={5,5,5,5,5}.
Output: 7
Explanation: After 5 operations, each element of the array become 6, and similarly after the next 5 operations, each element of the array become 7.

Input: M=7, K=2, arr={5,9,3,6,4,3};
Output: 5
Explanation: Can use 5 operations to increase the 3 smallest values to 5. Cannot further improve 2-nd smallest with the remaining 2 operations.

Input: M=10,K=4, arr={1,2,3,4,5};
Output: 5
Explanation: Can perform operations to fill all values to 5. The 4-th smallest value is thus 5.

Approach/Intuition:

Binary Search:

One way is to use binary search to find the maximum such answer value that can be achieved by distributing M among K values. If the current mid value is feasible, then the value of the mid is stored as our potential answer, and the search is continued in the upper half of that current search range. Otherwise, the search is continued in the lower half of the search range.

Follow the below steps to implement the above approach:

  • First, initialize the input array and variables M and K, and call to getVal function, to return us the answer.
  • Now, inside the getVal function,
    • sort the array.
    • initialize the search range from 0 to 1e9.
    • for current mid value, check it is valid or not, if it is valid store it as our answer, and change the range to upper half, otherwise if not valid, change the search range to lower half.

Below is the code to implement the above steps:

C++14




// C++ code to implement the above approach.
#include <bits/stdc++.h>
using namespace std;
 
//  check function to validate our selected kth largest
//  value.
bool check(int mid, int M, int K, vector<int>& arr)
{
    vector<int> temp;
    for (int i = 0; i < arr.size(); i++) {
        if (arr[i] < mid) {
            temp.push_back(arr[i]);
        }
    }
 
    if (temp.size() < K)
        return 1;
 
    for (int i = 0; i < temp.size(); i++) {
        if (M + temp[i] < mid)
            return 0;
        int minVal = min(M, mid - temp[i]);
 
        temp[i] += minVal;
        M -= minVal;
    }
 
    return 1;
}
 
//  binary search over the range for finding the exact
//  answer.
int getVal(int& M, int& K, vector<int>& arr)
{
    sort(arr.begin(), arr.end());
    int lo = 0, hi = 1e9;
    int ans;
    while (lo <= hi) {
        int mid = (lo + hi) / 2;
 
        if (check(mid, M, K, arr)) {
            ans = mid;
            lo = mid + 1;
        }
        else
            hi = mid - 1;
    }
 
    return ans;
}
 
// Driver's code
int main()
{
    int M = 10, K = 4;
 
    vector<int> arr = { 1, 2, 3, 4, 5 };
 
    cout << getVal(M, K, arr);
    return 0;
}


Java




// C++ code to implement the above approach.
import java.util.*;
 
public class Main {
    //  check function to validate our selected kth largest
    //  value.
    static boolean check(int mid, int M, int K,
                         List<Integer> arr)
    {
        List<Integer> temp = new ArrayList<>();
        for (int i = 0; i < arr.size(); i++) {
            if (arr.get(i) < mid) {
                temp.add(arr.get(i));
            }
        }
 
        if (temp.size() < K)
            return true;
 
        for (int i = 0; i < temp.size(); i++) {
            if (M + temp.get(i) < mid)
                return false;
            int minVal = Math.min(M, mid - temp.get(i));
 
            temp.set(i, temp.get(i) + minVal);
            M -= minVal;
        }
 
        return true;
    }
 
    //  binary search over the range for finding the exact
    //  answer.
    static int getVal(int M, int K, List<Integer> arr)
    {
        Collections.sort(arr);
        int lo = 0, hi = (int)1e9;
        int ans = 0;
        while (lo <= hi) {
            int mid = (lo + hi) / 2;
 
            if (check(mid, M, K, arr)) {
                ans = mid;
                lo = mid + 1;
            }
            else
                hi = mid - 1;
        }
 
        return ans;
    }
 
    // Driver's code
    public static void main(String[] args)
    {
        int M = 10, K = 4;
 
        List<Integer> arr
            = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
 
        System.out.println(getVal(M, K, arr));
    }
}
// This code is contributed by chetan bargal(chetanb13)


Python3




# Python3 code to implement the above approach.
from typing import List
 
# check function to validate our selected kth largest value.
def check(mid: int, M: int, K: int, arr: List[int]) -> bool:
    temp = []
    for i in range(len(arr)):
        if arr[i] < mid:
            temp.append(arr[i])
 
    if len(temp) < K:
        return True
 
    for i in range(len(temp)):
        if M + temp[i] < mid:
            return False
        minVal = min(M, mid - temp[i])
 
        temp[i] += minVal
        M -= minVal
 
    return True
 
# binary search over the range for finding the exact answer.
def getVal(M: int, K: int, arr: List[int]) -> int:
    arr.sort()
    lo = 0
    hi = 10**9
    ans = 0
 
    while lo <= hi:
        mid = (lo + hi) // 2
 
        if check(mid, M, K, arr):
            ans = mid
            lo = mid + 1
        else:
            hi = mid - 1
 
    return ans
 
# Drive code
if __name__ == '__main__':
    M = 10
    K = 4
    arr = [1, 2, 3, 4, 5]
    print(getVal(M, K, arr))
 
 # This Code is contributed by nikhilsainiofficial546


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program {
    // Check function to validate our selected kth largest
    // value.
    static bool Check(int mid, int M, int K, List<int> arr)
    {
        List<int> temp = new List<int>();
        for (int i = 0; i < arr.Count; i++) {
            if (arr[i] < mid) {
                temp.Add(arr[i]);
            }
        }
 
        if (temp.Count < K)
            return true;
 
        for (int i = 0; i < temp.Count; i++) {
            if (M + temp[i] < mid)
                return false;
            int minVal = Math.Min(M, mid - temp[i]);
 
            temp[i] += minVal;
            M -= minVal;
        }
 
        return true;
    }
 
    // Binary search over the range for finding the exact
    // answer.
    static int GetVal(ref int M, ref int K, List<int> arr)
    {
        arr.Sort();
        int lo = 0, hi = 1000000000;
        int ans = 0;
        while (lo <= hi) {
            int mid = (lo + hi) / 2;
 
            if (Check(mid, M, K, arr)) {
                ans = mid;
                lo = mid + 1;
            }
            else
                hi = mid - 1;
        }
 
        return ans;
    }
//Driver code
    static void Main(string[] args)
    {
        int M = 10, K = 4;
 
        List<int> arr = new List<int>() { 1, 2, 3, 4, 5 };
 
        Console.WriteLine(GetVal(ref M, ref K, arr));
    }
}


Javascript




// Javascript code to implement the above approach.
 
//  check function to validate our selected kth largest
//  value.
function check(mid, M, K, arr) {
let temp = [];
for (let i = 0; i < arr.length; i++) {
    if (arr[i] < mid) {
        temp.push(arr[i]);
    }
}
 
if (temp.length < K)
    return true;
 
for (let i = 0; i < temp.length; i++) {
    if (M + temp[i] < mid)
        return false;
    let minVal = Math.min(M, mid - temp[i]);
 
    temp[i] += minVal;
    M -= minVal;
}
 
return true;
}
 
//  binary search over the range for finding the exact
//  answer.
function getVal(M, K, arr) {
arr.sort((a, b) => a - b);
let lo = 0, hi = 1e9;
let ans;
while (lo <= hi) {
    let mid = Math.floor((lo + hi) / 2);
 
    if (check(mid, M, K, arr)) {
        ans = mid;
        lo = mid + 1;
    }
    else
        hi = mid - 1;
}
 
return ans;
}
 
// Driver's code
let M = 10, K = 4;
let arr = [1, 2, 3, 4, 5];
 
console.log(getVal(M, K, arr));
 
// This code is contributed by Vaibhav Nandan


Output

5

Time Complexity: O(NlogN), where N is the size of the ‘arr’ vector, as it involves iterating through the entire vector once. The time complexity of the ‘getVal’ function is O(N log N), where N is the size of the ‘arr’ vector, as it involves sorting the ‘arr’ vector and performing a binary search on it.
Auxiliary Space: O(N), as it involves storing the ‘arr’ vector and the ‘temp’ vector inside the ‘check’ function.



Last Updated : 22 Aug, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads