 Open in App
Not now

# Minimize the max of Array by breaking array elements at most K times

• Last Updated : 23 Mar, 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

## An approach using Binary Search:

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 ``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``; imax) {``            ``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`

Output

`2`

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:

1. Initialize a priority queue with the elements of the given array.
2. Initialize a variable max_element with the maximum element of the priority queue.
3. Repeat the following K times or until max_element becomes 1 or less than 1:
4. Extract the maximum element from the priority queue and store it in a variable element.
5. Break element into two halves and insert both halves back into the priority queue.
6. Update max_element with the maximum element of the priority queue.
7. If max_element becomes 1 or less than 1, break the loop.
8. Return max_element.

Below is the implementation of the above approach:

## C++

 `#include ``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 ``where` `T : IComparable``    ``{``        ``List data;` `        ``// Constructor``        ``public` `PriorityQueue()``        ``{``            ``this``.data = ``new` `List();``        ``}` `        ``// Overloaded constructor``        ``public` `PriorityQueue(IEnumerable collection)``        ``{``            ``this``.data = ``new` `List(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;``        ``}` `        ``// 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;``        ``}``    ``}``}`

Output

`2`

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

My Personal Notes arrow_drop_up