Given an array arr[] consisting of N positive integers and a positive integer K, the task is to minimize the maximum element present in the array by splitting at most K array elements into two numbers equal to their value.
Examples:
Input: arr[] = {2, 4, 8, 2}, K = 4
Output: 2
Explanation:
Following sequence of operations are required to be performed:
Operation 1: Splitting arr[1] (= 4) to {2, 2} modifies the array to {2, 2, 2, 8, 2}.
Operation 2: Splitting arr[3] (= 8) to {2, 6} modifies the array to {2, 2, 2, 2, 6, 2}.
Operation 3: Splitting arr[4] (= 6) to {2, 4} modifies the array to {2, 2, 2, 2, 2, 4, 2}.
Operation 4: Splitting arr[5] (= 4) to {2, 2} modifies the array to {2, 2, 2, 2, 2, 2, 2, 2}.
After completing the above operations, the maximum element present in the array is 2.
Input: arr[] = {7, 17}, K = 2
Output: 7
Approach: The given problem can be solved based on the following observations:
- If X can be the maximum element in the array arr[] by performing at most K operations, then there exists some value K (K > X), which can also be the maximum element present in the array arr[] by performing at most K splitting of the array elements.
- If X can’t be the maximum element in the array A[] by performing at most K operations, then there exists some value K (K < X) which can also not be the maximum element in the array arr[] by performing at most K splits of array elements.
- Therefore, the idea is to use Binary Search for finding the value over the range [1, INT_MAX] which can be the possible maximum value after at most K splits.
Follow the steps below to solve the problem:
- Initialize two variables, say low and high as 1 and the maximum element in the array arr[] respectively.
- Iterate until low is less than high and perform the following steps:
- Find the middle value of the range [low, high] as mid = (low + high)/2.
- Initialize a variable, say count, to store the maximum number of splits of array elements required to make the maximum element equal to mid.
- Traverse the given array arr[] and update the value of count as (arr[i] – 1) / mid to count the number of splits required.
- If the value of count is at most K, then update the value of high as mid.
- Otherwise, update the value of low as (mid + 1).
- After completing the above steps, print the value of high as the resultant maximum element present in the array obtained.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int possible( int A[], int N,
int mid, int K)
{
int count = 0;
for ( int i = 0; i < N; i++) {
count += (A[i] - 1) / mid;
}
return count <= K;
}
int minimumMaximum( int A[], int N, int K)
{
int lo = 1;
int hi = *max_element(A, A + N);
int mid;
while (lo < hi) {
mid = (lo + hi) / 2;
if (possible(A, N, mid, K)) {
hi = mid;
}
else {
lo = mid + 1;
}
}
return hi;
}
int main()
{
int arr[] = { 2, 4, 8, 2 };
int K = 4;
int N = sizeof (arr) / sizeof (arr[0]);
cout << minimumMaximum(arr, N, K);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean possible( int A[], int N,
int mid, int K)
{
int count = 0 ;
for ( int i = 0 ; i < N; i++)
{
count += (A[i] - 1 ) / mid;
}
return count <= K;
}
static int minimumMaximum( int A[], int N, int K)
{
int lo = 1 ;
Arrays.sort(A);
int hi = A[N - 1 ];
int mid;
while (lo < hi)
{
mid = (lo + hi) / 2 ;
if (possible(A, N, mid, K))
{
hi = mid;
}
else
{
lo = mid + 1 ;
}
}
return hi;
}
public static void main (String[] args)
{
int arr[] = { 2 , 4 , 8 , 2 };
int K = 4 ;
int N = arr.length;
System.out.println(minimumMaximum(arr, N, K));
}
}
|
Python3
def possible(A, N, mid, K):
count = 0
for i in range (N):
count + = (A[i] - 1 ) / / mid
return count < = K
def minimumMaximum(A, N, K):
lo = 1
hi = max (A)
while (lo < hi):
mid = (lo + hi) / / 2
if (possible(A, N, mid, K)):
hi = mid
else :
lo = mid + 1
return hi
if __name__ = = '__main__' :
arr = [ 2 , 4 , 8 , 2 ]
K = 4
N = len (arr)
print (minimumMaximum(arr, N, K))
|
C#
using System;
class GFG{
static bool possible( int [] A, int N,
int mid, int K)
{
int count = 0;
for ( int i = 0; i < N; i++)
{
count += (A[i] - 1) / mid;
}
return count <= K;
}
static int minimumMaximum( int [] A, int N, int K)
{
int lo = 1;
Array.Sort(A);
int hi = A[N - 1];
int mid;
while (lo < hi)
{
mid = (lo + hi) / 2;
if (possible(A, N, mid, K))
{
hi = mid;
}
else
{
lo = mid + 1;
}
}
return hi;
}
public static void Main( string [] args)
{
int [] arr = { 2, 4, 8, 2 };
int K = 4;
int N = arr.Length;
Console.WriteLine(minimumMaximum(arr, N, K));
}
}
|
Javascript
<script>
function possible(A, N, mid, K)
{
var count = 0;
var i;
for (i = 0; i < N; i++) {
count += Math.floor((A[i] - 1) / mid);
}
if (count <= K)
return true ;
else
return false
}
function minimumMaximum(A, N, K)
{
var lo = 1;
var hi = Math.max.apply(Math,A);
var mid;
while (lo < hi) {
mid = Math.floor((lo + hi) / 2);
if (possible(A, N, mid, K)) {
hi = mid;
}
else {
lo = mid + 1;
}
}
return hi;
}
var arr = [2, 4, 8, 2];
var K = 4;
var N = arr.length;
document.write(minimumMaximum(arr, N, K));
</script>
|
Time Complexity: O(N * log M), where M is the maximum element of the array.
Auxiliary Space: O(1)