Minimize the max of Array by breaking array elements at most K times
Last Updated :
04 Apr, 2023
Given an integer array arr[] of size N and a positive integer K, the task is to minimize the maximum of the array by replacing any element arr[i] into two positive elements (X, Y) at most K times such that arr[i] = X + Y.
Examples:
Input: arr = {9}, K = 2
Output: 3
Explanation: Operation 1: Replace element 9 into {6, 3} then array becomes {6, 3}.
Operation 2: Replace element 6 into {3, 3} then array becomes {3, 3, 3}.
So, the maximum element in arr[] after performing at most K operations are 3.
Input: arr = {2, 4, 8, 2}, K = 4
Output: 2
The problem can be solved using binary search based on the following idea:
Initialize start with minimum possible answer and end with maximum possible answer, then calculate the threshold value mid = (start + end) /2 and check if it is possible to make every element less than or equals to mid in at most K operations. If it is possible, update the result and shift end of range to mid - 1. Otherwise, shift start of range to mid + 1.
Follow the steps below to implement the above idea:
- Initialize a variable start = 1 and end = maximum possible answer.
- Initialize a variable result that will store the answer
- While start ? end
- Calculate mid = (start + end) / 2
- Calculate the maximum number of operations required to make every element less than or equal to mid.
- Iterate over the given array
- Check if the current element is greater than mid
- If true, then calculate the operation required to make this element less than or equals to mid
- Check if the total operation required to make every element less than or equal to mid is greater less than equal to K
- If true, update the result and move the end to mid - 1
- Otherwise, move the start to mid + 1.
- Return the result.
Below is the implementation of the above approach.
C++
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Function to find the minimum of maximum
int minimizeMaxElement(vector<int>& arr, int K)
{
// Initialize a variable start = 1 and
// end = maximum possible answer.
int start = 1,
end = *max_element(arr.begin(), arr.end());
// Initialize a variable result which
// will store the answer
int result = -1;
// Do while start <= end
while (start <= end) {
// Calculate mid = (start + end) / 2;
int mid = (start + end) >> 1;
// Calculate maximum number of
// operation required to make
// every element less than or
// equal to mid.
int operation = 0;
// Iterate over the given array
for (int i = 0; i < arr.size(); i++) {
// Check if current element is
// greater than mid, If true,
// then calculate the operation
// required to make this element
// less than or equals to mid
if (arr[i] > mid) {
operation += ceil((double)arr[i] / mid) - 1;
}
}
// Check if total operation
// required to make every element
// less than or equal to mid is
// greater less than equal to K
// If true, update the result and
// move the end to mid - 1
if (operation <= K) {
result = mid;
end = mid - 1;
}
else {
start = mid + 1;
}
}
// Return the result.
return result;
}
// Driver code
int main()
{
vector<int> arr = { 2, 4, 8, 2 };
int K = 4;
// Functions call
cout << minimizeMaxElement(arr, K);
return 0;
}
Java
// Java code to implement the approach
import java.io.*;
public class GFG {
// Function to find the minimum of maximum
static int minimizeMaxElement(int []arr, int K)
{
// Initialize a variable start = 1 and
// end = maximum possible answer.
int start = 1;
int max = 0;
for(int i=0; i<arr.length; i++ ) {
if(arr[i]>max) {
max = arr[i];
}
}
int end = max;
// Initialize a variable result which
// will store the answer
int result = -1;
// Do while start <= end
while (start <= end) {
// Calculate mid = (start + end) / 2;
int mid = (start + end) >> 1;
// Calculate maximum number of
// operation required to make
// every element less than or
// equal to mid.
int operation = 0;
// Iterate over the given array
for (int i = 0; i < arr.length; i++) {
// Check if current element is
// greater than mid, If true,
// then calculate the operation
// required to make this element
// less than or equals to mid
if (arr[i] > mid) {
operation += Math.ceil((double)arr[i] / mid) - 1;
}
}
// Check if total operation
// required to make every element
// less than or equal to mid is
// greater less than equal to K
// If true, update the result and
// move the end to mid - 1
if (operation <= K) {
result = mid;
end = mid - 1;
}
else {
start = mid + 1;
}
}
// Return the result.
return result;
}
// Driver code
public static void main (String[] args) {
int []arr = { 2, 4, 8, 2 };
int K = 4;
// Functions call
System.out.println(minimizeMaxElement(arr, K));
}
}
// This code is contributed by AnkThon
Python3
# Python3 code to implement the above approach
from math import *
# Function to find the minimum of maximum
def minimizeMaxElement(arr, K) :
# Initialize a variable start = 1 and
# end = maximum possible answer.
start = 1;
end = max(arr)
# Initialize a variable result which
# will store the answer
result = -1;
# Do while start <= end
while (start <= end) :
# Calculate mid = (start + end) / 2;
mid = (start + end) >> 1;
# Calculate maximum number of
# operation required to make
# every element less than or
# equal to mid.
operation = 0;
# Iterate over the given array
for i in range(len(arr)) :
# Check if current element is
# greater than mid, If true,
# then calculate the operation
# required to make this element
# less than or equals to mid
if (arr[i] > mid) :
operation += ceil(arr[i] / mid) - 1;
# Check if total operation
# required to make every element
# less than or equal to mid is
# greater less than equal to K
# If true, update the result and
# move the end to mid - 1
if (operation <= K) :
result = mid;
end = mid - 1;
else :
start = mid + 1;
# Return the result.
return result;
# Driver code
if __name__ == "__main__" :
arr = [ 2, 4, 8, 2 ];
K = 4;
# Functions call
print(minimizeMaxElement(arr, K));
# This code is contributed by AnkThon
C#
// C# code to implement the approach
using System;
class GFG {
// Function to find the minimum of maximum
static int minimizeMaxElement(int[] arr, int K)
{
// Initialize a variable start = 1 and
// end = maximum possible answer.
int start = 1;
int max = 0;
for (int i = 0; i < arr.Length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
int end = max;
// Initialize a variable result which
// will store the answer
int result = -1;
// Do while start <= end
while (start <= end) {
// Calculate mid = (start + end) / 2;
int mid = (start + end) >> 1;
// Calculate maximum number of
// operation required to make
// every element less than or
// equal to mid.
double operation = 0;
// Iterate over the given array
for (int i = 0; i < arr.Length; i++) {
// Check if current element is
// greater than mid, If true,
// then calculate the operation
// required to make this element
// less than or equals to mid
if (arr[i] > mid) {
operation
+= Math.Ceiling((float)arr[i] / mid)
- 1;
}
}
// Check if total operation
// required to make every element
// less than or equal to mid is
// greater less than equal to K
// If true, update the result and
// move the end to mid - 1
if (operation <= K) {
result = mid;
end = mid - 1;
}
else {
start = mid + 1;
}
}
// Return the result.
return result;
}
// Driver code
public static void Main()
{
int[] arr = { 2, 4, 8, 2 };
int K = 4;
// Functions call
Console.WriteLine(minimizeMaxElement(arr, K));
}
}
// This code is contributed by Samim Hossain Mondal.
JavaScript
// JavaScript code for the above approach
// Function to find the minimum of maximum
function minimizeMaxElement(arr, K)
{
// Initialize a variable start = 1 and
// end = maximum possible answer.
let start = 1, end = Math.max(... arr);
// Initialize a variable result which
// will store the answer
let result = -1;
// Do while start <= end
while (start <= end) {
// Calculate mid = (start + end) / 2;
let mid = Math.floor((start + end) >> 1);
// Calculate maximum number of
// operation required to make
// every element less than or
// equal to mid.
let operation = 0;
// Iterate over the given array
for (let i = 0; i < arr.length; i++) {
// Check if current element is
// greater than mid, If true,
// then calculate the operation
// required to make this element
// less than or equals to mid
if (arr[i] > mid) {
operation += Math.ceil(arr[i] / mid) - 1;
}
}
// Check if total operation
// required to make every element
// less than or equal to mid is
// greater less than equal to K
// If true, update the result and
// move the end to mid - 1
if (operation <= K) {
result = mid;
end = mid - 1;
}
else {
start = mid + 1;
}
}
// Return the result.
return result;
}
// Driver code
let arr = [ 2, 4, 8, 2 ];
let K = 4;
// Functions call
console.log(minimizeMaxElement(arr, K));
// This code is contributed by Potta Lokesh
Time Complexity: O(log2(max(arr)) * N), where max(arr) is the maximum element and N is the size of the given array.
Auxiliary Space: O(1)
Another Approach: Greedy approach with a priority queue
Another approach to solve this problem is to use a priority queue. First, we insert all the elements of the given array into the priority queue. Then, we extract the maximum element from the priority queue, break it into two halves, and insert both halves back into the priority queue. We repeat this process K times or until the maximum element in the priority queue becomes 1 or less than 1.
The idea behind this approach is that breaking a large element into two halves reduces the maximum element of the array. By repeating this process, we can gradually reduce the maximum element of the array until it becomes 1 or less than 1.
The steps of this approach are:
- Initialize a priority queue with the elements of the given array.
- Initialize a variable max_element with the maximum element of the priority queue.
- Repeat the following K times or until max_element becomes 1 or less than 1:
- Extract the maximum element from the priority queue and store it in a variable element.
- Break element into two halves and insert both halves back into the priority queue.
- Update max_element with the maximum element of the priority queue.
- If max_element becomes 1 or less than 1, break the loop.
- Return max_element.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int minimizeMaxElement(vector<int>& arr, int K)
{
priority_queue<int> pq(arr.begin(), arr.end());
int max_element = pq.top();
while (K--) {
int element = pq.top();
pq.pop();
int half = element / 2;
pq.push(half);
pq.push(element - half);
max_element = pq.top();
if (max_element <= 1) {
break;
}
}
return max_element;
}
int main()
{
vector<int> arr = { 9 };
int K;
arr = { 2, 4, 8, 2 };
K = 4;
cout << minimizeMaxElement(arr, K) << endl;
return 0;
}
Python3
import heapq
def minimizeMaxElement(arr, K):
# Initialize a max heap with the elements in the array
pq = [-a for a in arr]
heapq.heapify(pq)
# Pop the largest element from the heap, divide it by 2, and add the halves
# back to the heap until K iterations or the largest element is 1
max_element = -pq[0]
for i in range(K):
element = -heapq.heappop(pq)
half = element // 2
heapq.heappush(pq, -half)
heapq.heappush(pq, -(element - half))
max_element = -pq[0]
if max_element <= 1:
break
# Return the largest element in the heap (i.e., the smallest max element)
return max_element
# Driver program
arr = [9]
K = 3
arr = [2, 4, 8, 2]
K = 4
print(minimizeMaxElement(arr, K))
C#
using System;
using System.Collections.Generic;
using System.Linq;
namespace minimizeMaxElement {
class Program {
static void Main(string[] args)
{
List<int> arr = new List<int>{ 9 };
int K;
arr = new List<int>{ 2, 4, 8, 2 };
K = 4;
Console.WriteLine(MinimizeMaxElement(arr, K));
}
// Function to reduce the maximum element in array to 1
// through the K operations
static int MinimizeMaxElement(List<int> arr, int K)
{
// Create a priority queue
PriorityQueue<int> pq = new PriorityQueue<int>(arr);
int max_element = pq.Peek();
// While K is not 0
while (K-- > 0) {
// Pop the top element from the priority queue
int element = pq.Pop();
// Calculate the half of the element
int half = element / 2;
// Push the half and the difference of the
// element and half to the priority queue
pq.Push(half);
pq.Push(element - half);
// Update the maximum element
max_element = pq.Peek();
// If the maximum element is 1, break the loop
if (max_element <= 1)
break;
}
// Return the maximum element
return max_element;
}
}
// Generic Priority Queue class
public class PriorityQueue<T> where T : IComparable<T> {
List<T> data;
// Constructor
public PriorityQueue() { this.data = new List<T>(); }
// Overloaded constructor
public PriorityQueue(IEnumerable<T> collection)
{
this.data = new List<T>(collection);
for (int i = (data.Count / 2) - 1; i >= 0; i--)
HeapifyDown(i);
}
// Function to get the size of the priority queue
public int Count() { return data.Count; }
// Function to check if the priority queue is empty
public bool IsEmpty() { return Count() == 0; }
// Function to get the top element of the priority queue
public T Peek()
{
if (IsEmpty())
throw new Exception("Priority queue is empty.");
return data[0];
}
// Function to pop the top element from the priority
// queue
public T Pop()
{
if (IsEmpty())
throw new Exception("Priority queue is empty.");
T element = Peek();
Swap(0, Count() - 1);
data.RemoveAt(Count() - 1);
HeapifyDown(0);
return element;
}
// Function to push an element to the priority queue
public void Push(T item)
{
data.Add(item);
HeapifyUp(Count() - 1);
}
// Function to heapify up
private void HeapifyUp(int index)
{
if (index == 0)
return;
int parentIndex = (index - 1) / 2;
if (data[index].CompareTo(data[parentIndex]) > 0) {
Swap(index, parentIndex);
HeapifyUp(parentIndex);
}
}
// Function to heapify down
private void HeapifyDown(int index)
{
int leftIndex = (2 * index) + 1;
int rightIndex = (2 * index) + 2;
int largestIndex = index;
if (leftIndex < Count()
&& data[leftIndex].CompareTo(data[largestIndex])
> 0)
largestIndex = leftIndex;
if (rightIndex < Count()
&& data[rightIndex].CompareTo(
data[largestIndex])
> 0)
largestIndex = rightIndex;
if (largestIndex != index) {
Swap(index, largestIndex);
HeapifyDown(largestIndex);
}
}
// Function to swap two elements
private void Swap(int firstIndex, int secondIndex)
{
T temp = data[firstIndex];
data[firstIndex] = data[secondIndex];
data[secondIndex] = temp;
}
}
}
Java
import java.util.*;
class Main {
public static int minimizeMaxElement(List<Integer> arr,
int K)
{
// Initialize a max heap with the elements in the
// array
PriorityQueue<Integer> pq = new PriorityQueue<>(
Collections.reverseOrder());
pq.addAll(arr); // add all elements of the list to
// the priority queue
int maxElement
= pq.peek(); // get the largest element in the
// priority queue
while (
K > 0) { // repeat the following process K times
int element
= pq.poll(); // remove the largest element
// from the priority queue
int half
= element / 2; // divide the element by 2
pq.offer(half); // add the first half back to
// the priority queue
pq.offer(element
- half); // add the second half back to
// the priority queue
maxElement
= pq.peek(); // get the new largest element
// in the priority queue
if (maxElement
<= 1) { // if the largest element is 1 or
// less, we cannot further divide
// the elements
break; // exit the loop
}
K--; // decrement the number of iterations left
}
return maxElement; // return the largest element in
// the priority queue (i.e., the
// smallest max element)
}
public static void main(String[] args)
{
List<Integer> arr = new ArrayList<>();
int K;
arr = Arrays.asList(
2, 4, 8, 2); // set the values of the array
K = 4; // set the number of iterations
System.out.println(minimizeMaxElement(
arr, K)); // call the minimizeMaxElement
// function and print the result
}
}
// Contributed by phasing17
JavaScript
function minimizeMaxElement(arr, K) {
let pq = new PriorityQueue();
pq.enqueue(...arr);
let max_element = pq.peek();
while (K--) {
let element = pq.dequeue();
let half = Math.floor(element / 2);
pq.enqueue(half);
pq.enqueue(element - half);
max_element = pq.peek();
if (max_element <= 1) {
break;
}
}
return max_element;
}
class PriorityQueue {
constructor() {
this.items = [];
}
enqueue(...items) {
items.forEach((item) => {
let added = false;
for (let i = 0; i < this.items.length; i++) {
if (item > this.items[i]) {
this.items.splice(i, 0, item);
added = true;
break;
}
}
if (!added) {
this.items.push(item);
}
});
}
dequeue() {
return this.items.shift();
}
peek() {
return this.items[0];
}
isEmpty() {
return this.items.length === 0;
}
size() {
return this.items.length;
}
}
let arr = [9];
let K;
arr = [2, 4, 8, 2];
K = 4;
console.log(minimizeMaxElement(arr, K));
// This code is contributed by sarojmcy2e
Time Complexity: O(K*logN), where N is the size of the array
Auxiliary Space: O(N), where N is the size of the array
Similar Reads
Minimize the max of Array by doing at most K increment and decrement
Given a positive array arr[] of size N (2 ⤠N ⤠105) and a positive integer K, the task is to minimize the maximum value of arr[] by performing at most K operations where in each operation, you can select any two distinct integers i and j (0 ⤠i, j < N), then increase the value of arr[i] by 1 and
9 min read
Minimize maximum array element by splitting array elements into powers of two at most K times
Given an array arr[] consisting of N positive integers and an integer K, the task is to minimize the maximum value of the array by splitting the array element into powers of 2 at most K times. Examples: Input: arr[] = {2, 4, 11, 2}, K = 2Output: 2Explanation:Below are the operations performed on arr
12 min read
Minimize maximum array element possible by at most K splits on the given array
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 = 4Output: 2Explanation:Following se
9 min read
Minimize the maximum of Array by replacing any element with other element at most K times
Given an array arr[] of size N and an integer K, the task is to minimize the value of the maximum element of the array arr[] after replacing any element of the array with any other element of that array at most K times. Examples: Input: arr[] = {5, 3, 3, 2, 1}, K = 3Output: 2Explanation: Replace the
8 min read
Maximize count of 1s in an array by repeated division of array elements by 2 at most K times
Given an array arr[] of size N and an integer K, the task to find the maximum number of array elements that can be reduced to 1 by repeatedly dividing any element by 2 at most K times. Note: For odd array elements, take its ceil value of division. Examples: Input: arr[] = {5, 8, 4, 7}, K = 5Output:
6 min read
Maximize the count of distinct elements in Array after at most K changes
Given an array arr[], the task is to find the maximum number of distinct numbers in arr after at most K changes. In each change pick any element X from arr and change it to Y such that L <= Y <= R. Examples: Input: arr[] = {1, 2, 1, 4, 6, 4, 4}, L = 1, R = 5 and K = 2Output: 6Explanation: Foll
8 min read
Maximize bitwise AND of Array by changing at most K bits of elements
Given an array arr[] of length N. You can perform at most K operations on the array of the following type: Choose an index i (0 ? i ? N-1) and set the j-th bit of arr[i] to 1 (0 ? j ? 30). The task is to find the maximum possible value of bitwise AND of all array elements after performing at most K
8 min read
Maximize Kth largest element after splitting the given Array at most C times
Given an array arr[] and two positive integers K and C, the task is to maximize the Kth maximum element obtained after splitting an array element arr[] into two parts(not necessarily an integer) C number of times. Print -1 if there doesn't exist Kth maximum element. Note: It is compulsory to do spli
7 min read
Maximize the minimum Array value by changing elements with adjacent K times
Given an array arr[] of N integers and an integer K, where K denotes the maximum number of operations which can be applied to the array, the task is to maximize the minimum value of arr[] by using the given operation at most K times. In one operation it is possible to select any element of the given
9 min read
Maximize first array element by performing given operations at most K times
Given an array arr[] of size N an integer K, the task is to find the maximize the first element of the array by performing the following operations at most K times: Choose a pair of indices i and j (0 ? i, j ? N-1) such that |i ? j| = 1 and arri > 0.Set arri = arri ? 1 and arrj = arrj + 1 on thos
7 min read