Related Articles

Related Articles

Count of Array elements to be divided by 2 to make at least K elements equal
  • Difficulty Level : Medium
  • Last Updated : 15 Oct, 2020

Given an integer array arr[] of size N, the task is to find the minimum number of array elements required to be divided by 2, to make at least K elements in the array equal.
Example : 

Input: arr[] = {1, 2, 2, 4, 5}, N = 5, K = 3 
Output:
Explanation: 
Dividing 4 by 2 modifies the array to {1, 2, 2, 2, 5} with 3 equal elements.
Input: arr[] = {1, 2, 3, 4, 5}, N = 5, K = 3 
Output:
Explanation: 
Dividing 2 and 3 by 2 modifies the array to {1, 1, 1, 4, 5} with 3 equal elements. 
 

Approach: 
Every integer X can be divided by 2 log2(X) times to get a non-zero value. Hence, we need to perform these log2(arr[i]) operations on every array element arr[i] and for every value obtained after a division, store the number of operations required to reach the respective value. Once, all operations are performed for all array elements, for every value that at least K array elements have been reduced to at some point, find the sum of smallest K operations required among all of them. Find the minimum number of operations required among all such instances.
 

Illustration: 
arr[] = {1, 2, 2, 4, 5}, N = 5, K = 3
Only 1 element can have a value 5, so ignore. 
Only 1 element can have a value 4, so ignore. 
No element can have a value 3.
4 elements can have a value 2. 
{1, 2, 2, (4/2), (5/2) } -> {1, 2, 2, 2, 2} 
Since, the number of possibilities exceeds K, find the sum of the smallest K operations. 
arr[1] -> 0 operations 
arr[2] -> 0 operations 
arr[3] -> 1 operation 
arr[4] -> 1 operation 
Hence, sum of smallest 3 operations = (0 + 0 + 1) = 1
All 5 elements can be reduced to 1. 
{1, 2/2, 2/2, (4/2)/2, (5/2)/2} -> {1, 1, 1, 1, 1} 
Hence, the sum of smallest 3 operations = (0 + 1 + 1) = 2
Hence, the minimum number of operations required to make at least K elements equal is 1. 
 

Follow the steps below to solve the problem using the above approach:  



  1. Create a matrix vals[][] such that vals [ X ][ j ] will store the number of operations needed to obtain value X from an array element.
  2. Traverse the array and for every array element: 
    • Initialize x = arr[i]. Initialize count of operations cur as 0.
    • At every step, update x = x/2 and increment cur by 1. Insert cur into vals[x] as the number of divisions required to obtain the current value of x.
  3. Now, all possible values that can be obtained by repetitive division of every arr[i] by 2 with the number of such divisions required to get that value are stored in the vals[][] matrix.
  4. Now, traverse the matrix vals[][] and for every row, perform the following: 
    • Check if the current row vals[i] consists of at least K elements or not. If vals[i] < K, ignore as at least K array elements cannot be reduced to i.
    • If vals[i].size() is ≥ K, calculate the sum of the row i. Update ans = min(ans, sum of vals[i]).
  5. The final value of ans gives us the desired answer.

Below is the implementation of the above approach :
 

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to make atleast
// K elements of the given array
// equal by dividing by 2
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the
// minimum number of divisions
// required
int get_min_opration(int arr[], int N,
                     int K)
{
    vector<vector<int> > vals(200001);
    for (int i = 0; i < N; ++i) {
        int x = arr[i];
 
        int cur = 0;
        while (x > 0) {
            // cur: number of
            // times a[i] is
            // divided by 2
            // to obtain x
            vals[x].push_back(cur);
            x /= 2;
            ++cur;
        }
    }
 
    int ans = INT_MAX;
    for (int i = 0; i <= 200000; ++i) {
        // To obtain minimum
        // number of operations
        sort(vals[i].begin(),
             vals[i].end());
    }
    for (int i = 0; i <= 200000; ++i) {
 
        // If it is not possible
        // to make at least K
        // elements equal to vals[i]
        if (int(vals[i].size()) < K)
            continue;
        // Store the number
        // of operations
        int sum = 0;
        for (int j = 0; j < K; j++) {
            sum += vals[i][j];
        }
        // Update the minimum
        // number of operations
        // required
        ans = min(ans, sum);
    }
 
    return ans;
}
// Driver Program
int main()
{
    int N = 5, K = 3;
 
    int arr[] = { 1, 2, 2, 4, 5 };
    cout << get_min_opration(arr, N, K);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to make atleast
// K elements of the given array
// equal by dividing by 2
import java.util.*;
class GFG{
 
// Function to return the
// minimum number of divisions
// required
static int get_min_opration(int arr[],
                            int N, int K)
{
  Vector<Integer> []vals = new Vector[200001];
   
  for (int i = 0; i < vals.length; i++)
    vals[i] = new Vector<Integer>();
   
  for (int i = 0; i < N; ++i)
  {
    int x = arr[i];
    int cur = 0;
     
    while (x > 0)
    {
      // cur: number of
      // times a[i] is
      // divided by 2
      // to obtain x
      vals[x].add(cur);
      x /= 2;
      ++cur;
    }
  }
 
  int ans = Integer.MAX_VALUE;
   
  for (int i = 0; i <= 200000; ++i)
  {
    // To obtain minimum
    // number of operations
    Collections.sort(vals[i]);
  }
   
  for (int i = 0; i <= 200000; ++i)
  {
    // If it is not possible
    // to make at least K
    // elements equal to vals[i]
    if ((vals[i].size()) < K)
      continue;
     
    // Store the number
    // of operations
    int sum = 0;
     
    for (int j = 0; j < K; j++)
    {
      sum += vals[i].get(j);
    }
     
    // Update the minimum
    // number of operations
    // required
    ans = Math.min(ans, sum);
  }
 
  return ans;
}
   
// Driver code
public static void main(String[] args)
{
  int N = 5, K = 3;
  int arr[] = {1, 2, 2, 4, 5};
  System.out.print(get_min_opration(arr, N, K));
}
}
 
// This code is contributed by shikhasingrajput

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to make atleast
# K elements of the given array
# equal by dividing by 2
import sys
 
# Function to return the
# minimum number of divisions
# required
def get_min_opration(arr, N, K):
     
    vals = [[] for _ in range(200001)]
    for i in range(N):
        x = arr[i]
 
        cur = 0
        while (x > 0):
             
            # cur: number of times a[i]
            # is divided by 2 to obtain x
            vals[x].append(cur)
            x //= 2
            cur += 1
 
    ans = sys.maxsize
    for i in range(200001):
         
        # To obtain minimum
        # number of operations
        vals[i] = sorted(vals[i])
 
    for i in range(200001):
 
        # If it is not possible
        # to make at least K
        # elements equal to vals[i]
        if (int(len(vals[i])) < K):
            continue
             
        # Store the number
        # of operations
        sum = 0
        for j in range(K):
            sum += vals[i][j]
             
        # Update the minimum
        # number of operations
        # required
        ans = min(ans, sum)
 
    return ans
 
# Driver code
if __name__ == '__main__':
     
    N = 5
    K = 3
    arr = [ 1, 2, 2, 4, 5 ]
     
    print(get_min_opration(arr, N, K))
 
# This code is contributed by mohit kumar 29

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to make atleast
// K elements of the given array
// equal by dividing by 2
using System;
using System.Collections.Generic;
class GFG{
 
// Function to return the
// minimum number of divisions
// required
static int get_min_opration(int []arr,
                            int N, int K)
{
  List<int> []vals =
              new List<int>[200001];
   
  for (int i = 0; i < vals.Length; i++)
    vals[i] = new List<int>();
   
  for (int i = 0; i < N; ++i)
  {
    int x = arr[i];
    int cur = 0;
     
    while (x > 0)
    {
      // cur: number of
      // times a[i] is
      // divided by 2
      // to obtain x
      vals[x].Add(cur);
      x /= 2;
      ++cur;
    }
  }
 
  int ans = int.MaxValue;
   
  for (int i = 0; i <= 200000; ++i)
  {
    // If it is not possible
    // to make at least K
    // elements equal to vals[i]
    if ((vals[i].Count) < K)
      continue;
     
    // Store the number
    // of operations
    int sum = 0;
     
    for (int j = 0; j < K; j++)
    {
      sum += vals[i][j];
    }
     
    // Update the minimum
    // number of operations
    // required
    ans = Math.Min(ans, sum);
  }
 
  return ans;
}
   
// Driver code
public static void Main(String[] args)
{
  int N = 5, K = 3;
  int []arr = {1, 2, 2, 4, 5};
  Console.Write(get_min_opration(arr, N, K));
}
}
 
// This code is contributed by shikhasingrajput

chevron_right


Output: 

1





 

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

competitive-programming-img




My Personal Notes arrow_drop_up
Recommended Articles
Page :