📌  相关文章
📜  要除以 2 以使至少 K 个元素相等的数组元素的计数

📅  最后修改于: 2021-09-08 11:36:44             🧑  作者: Mango

给定一个大小为N的整数数组arr[] ,任务是找到需要除以 2 的最小数组元素数,以使数组中至少K 个元素相等。
例子 :

方法:
每个整数X都可以除以 2 log 2 (X)次以获得非零值。因此,我们需要对每个数组元素 arr[i] 执行这些log 2 (arr[i])操作,并且对于除法后获得的每个值,存储达到相应值所需的操作数。一次,对所有数组元素执行所有操作,对于至少K 个数组元素在某个时刻减少到的每个值,找到所有这些元素中所需的最小K 个操作的总和。找出所有此类实例中所需的最少操作数。

按照以下步骤使用上述方法解决问题:

  1. 创建一个矩阵vals[][] ,这样vals [ X ][ j ]将存储从数组元素获取值X所需的操作数。
  2. 遍历数组和每个数组元素:
    • 初始化 x = arr[i]。操作CUR的初始化算作0。
    • 在每一步,更新x = x/2并将cur 增加 1 。将cur插入 vals[x] 作为获得x的当前值所需的除法数。
  3. 现在,可以通过将每个 arr[i] 重复除以 2 获得的所有可能值以及获得该值所需的此类除法次数都存储在vals[][]矩阵中。
  4. 现在,遍历矩阵vals[][]并对每一行执行以下操作:
    • 检查当前行vals[i] 是否至少包含K 个元素。如果vals[i] < K ,则忽略,因为至少 K 个数组元素不能减少到i
    • 如果vals[i].size() ≥ K ,则计算行i的总和。更新ans = min(ans, sum of vals[i])
  5. ans的最终值给了我们想要的答案。

下面是上述方法的实现:

C++
// C++ program to make atleast
// K elements of the given array
// equal by dividing by 2
 
#include 
using namespace std;
 
// Function to return the
// minimum number of divisions
// required
int get_min_opration(int arr[], int N,
                     int K)
{
    vector > 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;
}


Java
// 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 []vals = new Vector[200001];
   
  for (int i = 0; i < vals.length; i++)
    vals[i] = new Vector();
   
  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


Python3
# 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


C#
// 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 []vals =
              new List[200001];
   
  for (int i = 0; i < vals.Length; i++)
    vals[i] = new List();
   
  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


Javascript


输出:
1

时间复杂度: O (N * log N)
辅助空间: O (N * log N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live