📌  相关文章
📜  将Array元素的数量除以2,以使至少K个元素相等

📅  最后修改于: 2021-05-04 09:24:00             🧑  作者: 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个数组元素不能简化为i
    • 如果瓦尔斯[I] .size()≥K,计算行i的总和。更新ans = min(ans,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


输出:
1





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