Minimize maximum array element by splitting array elements into powers of two at most K times

Last Updated : 22 Feb, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

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 = 2
Output: 2
Explanation:
Below are the operations performed on array elements at most K(= 2) times:
Operation 1: Remove the element at index 2, i.e., arr[2] = 11 and replace it with 11 numbers of 1s in it. Now the array arr[] modifies to {2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2}.
Operation 2: Remove the element at index 1, i.e., arr[1] = 4 and replace it with 4 numbers of 1s in it. Now the array arr[] modifies to {2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2}.

After performing the above operations, the maximum value of the array is 2, which is minimum possible value.

Input: arr[]= {9}, K = 2
Output: 1

Approach: The given problem can be solved by using the fact that every number can be expressed the sum of 1 which is a power of 2. Follow the steps below to solve the problem:

Below is the implementation of the above approach:

C++
// C++ program for the above approach

#include <bits/stdc++.h>
using namespace std;

// Function to find the minimum value
// of the maximum element of the array
// by splitting at most K array element
// into perfect powers of 2
void minimumSize(int arr[], int N, int K)
{
    // Sort the array element in
    // the ascending order
    sort(arr, arr + N);

    // Reverse the array
    reverse(arr, arr + N);

    // If count of 0 is equal to N
    if (count(arr, arr + N, 0) == N)
        cout << 0;

    // Otherwise, if K is greater
    // than or equal to N
    else if (K >= N)
        cout << 1 << endl;

    // Otherwise
    else
        cout << arr[K] << endl;
}

// Driver Code
int main()
{
    int arr[] = { 2, 4, 8, 2 };
    int K = 2;
    int N = sizeof(arr) / sizeof(arr[0]);
    minimumSize(arr, N, K);

    return 0;
}
Java
// Java program for the above approach
import java.lang.*;
import java.util.*;

class GFG{

// Function to find the minimum value
// of the maximum element of the array
// by splitting at most K array element
// into perfect powers of 2
static void minimumSize(int arr[], int N, int K)
{
    
    // Sort the array element in
    // the ascending order
    Arrays.sort(arr);

    // Reverse the array
    reverse(arr);

    // If count of 0 is equal to N
    if (count(arr, 0) == N)
        System.out.println(0);

    // Otherwise, if K is greater
    // than or equal to N
    else if (K >= N)
        System.out.println(1);

    // Otherwise
    else
        System.out.println(arr[K]);
}

static void reverse(int[] a)
{
    int i, k, t;
    int n = a.length;
    
    for(i = 0; i < n / 2; i++)
    {
        t = a[i];
        a[i] = a[n - i - 1];
        a[n - i - 1] = t;
    }
}

static int count(int[] a, int n)
{
    int freq = 0;
    
    for(int i = 0; i < a.length; i++)
    {
        if (a[i] == n)
            freq++;
    }
    return freq;
}

// Driver code
public static void main(String[] args)
{
    int arr[] = { 2, 4, 8, 2 };
    int K = 2;
    int N = arr.length;
    
    minimumSize(arr, N, K);
}
}

// This code is contributed by offbeat
Python
# Python program for the above approach

# Function to find the minimum value
# of the maximum element of the array
# by splitting at most K array element
# into perfect powers of 2
def minimumSize(arr, N, K):
  
    # Sort the array element in
    # the ascending order
    arr.sort()
    
    # Reverse the array
    arr.reverse()
    
    # If count of 0 is equal to N
    zero = arr.count(0)
    if zero == N:
        print(0)
        
    # Otherwise, if K is greater
    # than or equal to N
    elif K >= N:
        print(1)
        
    # Otherwise
    else:
        print(arr[K])

# Driver Code
arr = [2, 4, 8, 2]
K = 2
N = len(arr)
minimumSize(arr, N, K)

# This code is contributed by sudhanshugupta2019a.
C#
// C#program for the above approach
using System;
class GFG 
{

    // Function to find the minimum value
    // of the maximum element of the array
    // by splitting at most K array element
    // into perfect powers of 2
    static void minimumSize(int[] arr, int N, int K)
    {

        // Sort the array element in
        // the ascending order
        Array.Sort(arr);

        // Reverse the array
        Array.Reverse(arr);

        // If count of 0 is equal to N
        if (count(arr, 0) == N)
            Console.WriteLine(0);

        // Otherwise, if K is greater
        // than or equal to N
        else if (K >= N)
            Console.WriteLine(1);

        // Otherwise
        else
            Console.WriteLine(arr[K]);
    }

    static void reverse(int[] a)
    {
        int i, t;
        int n = a.Length;

        for (i = 0; i < n / 2; i++) {
            t = a[i];
            a[i] = a[n - i - 1];
            a[n - i - 1] = t;
        }
    }

    static int count(int[] a, int n)
    {
        int freq = 0;

        for (int i = 0; i < a.Length; i++) {
            if (a[i] == n)
                freq++;
        }
        return freq;
    }

    // Driver code
    public static void Main(string[] args)
    {
        int[] arr = { 2, 4, 8, 2 };
        int K = 2;
        int N = arr.Length;

        minimumSize(arr, N, K);
    }
}

// This code is contributed by ukasp.
JavaScript
<script>

// JavaScript program for the above approach

// Function to find the minimum value
// of the maximum element of the array
// by splitting at most K array element
// into perfect powers of 2
function minimumSize(arr,N,K)
{
    // Sort the array element in
    // the ascending order
    (arr).sort(function(a,b){return a-b;});
 
    // Reverse the array
    reverse(arr);
 
    // If count of 0 is equal to N
    if (count(arr, 0) == N)
        document.write(0);
 
    // Otherwise, if K is greater
    // than or equal to N
    else if (K >= N)
        document.write(1);
 
    // Otherwise
    else
        document.write(arr[K]);
}

function reverse(a)
{
    let i, k, t;
    let n = a.length;
     
    for(i = 0; i < n / 2; i++)
    {
        t = a[i];
        a[i] = a[n - i - 1];
        a[n - i - 1] = t;
    }
}

function count(a,n)
{
    let freq = 0;
     
    for(let i = 0; i < a.length; i++)
    {
        if (a[i] == n)
            freq++;
    }
    return freq;
}

// Driver code
let arr=[2, 4, 8, 2];
let K = 2;
let N = arr.length;
minimumSize(arr, N, K);


// This code is contributed by avanitrachhadiya2155

</script>

Output: 
2

 

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

Another efficient approach: In the previous approach, we are sorting the array and found the (K+1)th maximum element for the K<N. Instead of sorting the array, we can use a priority queue to find the (K+1)th maximum element.

The time complexity for this approach in the worst case is O(N*log(K)) for k<N otherwise, the time complexity is O(1). Hence the given approach is much better than the previous approach for a smaller value of k.

Below is the implementation of the above approach:

C++
// C++ program for the above approach

#include <bits/stdc++.h>
using namespace std;

// Function to find the minimum value
// of the maximum element of the array
// by splitting at most K array element
// into perfect powers of 2
void minimumSize(int arr[], int N, int K)
{
    // If count of 0 is equal to N
    if (count(arr, arr + N, 0) == N)
        cout << 0;

    // Otherwise, if K is greater
    // than or equal to N
    else if (K >= N)
        cout << 1 << endl;

    // Otherwise
    else
    {
    // Finding (K+1)th maximum element 
    // using a priority_queue
    priority_queue<int, vector<int>, greater<int> >pq;
 
    for (int i = 0; i < N; ++i) {
 
        // Insert elements into
        // the priority queue
        pq.push(arr[i]);
 
        // If size of the priority
        // queue exceeds k+1
        if (pq.size() > (K+1)) {
            pq.pop();
        }
    }
    // Print the (K+1)th maximum element
    cout<<pq.top()<<endl;
    }
}

// Driver Code
int main()
{
    int arr[] = { 2, 4, 8, 2 };
    int K = 2;
    int N = sizeof(arr) / sizeof(arr[0]);
    minimumSize(arr, N, K);

    return 0;
}

// This code is contributed by Pushpesh raj
Python3
# Python program for the above approach
import bisect

# Function to find the minimum value
# of the maximum element of the array
# by splitting at most K array element
# into perfect powers of 2
def minimumSize(arr,N,K):
    # If count of 0 is equal to N
    if(arr.count(0)==N):
        print(0)
    
    # Otherwise, if K is greater
    # than or equal to N
    elif(K>=N):
        print(1)
    
    # Otherwise
    else:
        # Finding (K+1)th maximum element
        # using a priority_queue
        pq=[]
        
        for i in range(N):
            # Insert elements into
            # the priority queue
            bisect.insort(pq,arr[i])
            
            # If size of the priority
            # queue exceeds k+1
            if(len(pq)>(K+1)):
                pq.pop()
        # Print the (K+1)th maximum element
        print(pq[0])
        
# Driver Code
arr=[2,4,8,2]
K=2
N=len(arr)
minimumSize(arr,N,K)

# This code is contributed by Aman Kumar.
Java
import java.util.PriorityQueue;

public class Main {

    // Function to find the minimum value of the maximum
    // element of the array by splitting at most K array
    // element into perfect powers of 2
    public static void minimumSize(int[] arr, int N, int K)
    {

        // If count of 0 is equal to N
        if (isZeroArray(arr, N)) {
            System.out.println(0);

            // Otherwise, if K is greater than or equal to N
        }
        else if (K >= N) {
            System.out.println(1);

            // Otherwise
        }
        else {
            // Finding (K+1)th maximum element using a
            // priority_queue
            PriorityQueue<Integer> pq
                = new PriorityQueue<>();

            for (int i = 0; i < N; ++i) {

                // Insert elements into the priority queue
                pq.add(arr[i]);

                // If size of the priority queue exceeds k+1
                if (pq.size() > (K + 1)) {
                    pq.poll();
                }
            }
            // Print the (K+1)th maximum element
            System.out.println(pq.peek());
        }
    }

    // Function to check if the given array only contains
    // zeros
    private static boolean isZeroArray(int[] arr, int N)
    {
        for (int i = 0; i < N; i++) {
            if (arr[i] != 0) {
                return false;
            }
        }
        return true;
    }

    // Driver code
    public static void main(String[] args)
    {
        int[] arr = { 2, 4, 8, 2 };
        int K = 2;
        int N = arr.length;
        minimumSize(arr, N, K);
    }
} // this code is contributed by devendra1
JavaScript
// Define a function to find the minimum value of the maximum
// element of the array by splitting at most K array element into perfect powers of 2
function minimumSize(arr, N, K)
{

    // If count of 0 is equal to N
    if (isZeroArray(arr, N)) {
    console.log(0);
    
     // Otherwise, if K is greater than or equal to N
     } 
    else if (K >= N) {
    console.log(1);
    // Otherwise
    } 
    else
    {
    
    // Finding (K+1)th maximum element using a priority_queue
    // Create an empty array to serve as the priority queue
    const pq = [];
    for (let i = 0; i < N; ++i)
    {
    
      // Insert elements into the priority queue
      pq.push(arr[i]);
      
      // Sort the array in descending order
      pq.sort((a, b) => b - a);
      
      // If size of the priority queue exceeds k+1
      if (pq.length > (K + 1))
      {
      
        // Remove the smallest element from the queue
        pq.pop();
      }
    }
    
    // Print the (K+1)th maximum element
    console.log(pq[K]);

    }
}

// Function to check if the given array only contains zeros
function isZeroArray(arr, N) {
    for (let i = 0; i < N; i++) {
          if (arr[i] !== 0) {
              return false;
              }
      }
  return true;
}

// Driver code
const arr = [2, 4, 8, 2];
const K = 2;
const N = arr.length;
minimumSize(arr, N, K);
C#
using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
  // Function to find the minimum value
  // of the maximum element of the array
  // by splitting at most K array element
  // into perfect powers of 2
  public static void minimumSize(int[] arr, int N, int K)
  {
      // If count of 0 is equal to N
      if (arr.Count(x => x == 0) == N)
      {
      Console.WriteLine(0);
      }
      // Otherwise, if K is greater
      // than or equal to N
      else if (K >= N)
      {
      Console.WriteLine(1);
      }
      // Otherwise
      else
      {
      // Finding (K+1)th maximum element
      // using a priority_queue
      var pq = new SortedSet<int>();
      foreach (var x in arr)
      {
          // Insert elements into
          // the priority queue
          pq.Add(x);
          // If size of the priority
                  // queue exceeds k+1
                  if (pq.Count > (K + 1))
                  {
                      pq.Remove(pq.Max);
                  }
              }
              // Print the (K+1)th maximum element
              Console.WriteLine(pq.Min);
          }
      }

  // Driver Code
  public static void Main()
  {
      int[] arr = { 2, 4, 8, 2 };
      int K = 2;
      int N = arr.Length;
      minimumSize(arr, N, K);
  }
}

Output
2

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


Next Article

Similar Reads