给定大小为N的整数数组arr [] ,任务是找到需要除以2的最小数组元素数,以使数组中的至少K个元素相等。
例子 :
Input: arr[] = {1, 2, 2, 4, 5}, N = 5, K = 3
Output: 1
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: 1
Explanation:
Dividing 2 and 3 by 2 modifies the array to {1, 1, 1, 4, 5} with 3 equal elements.
方法:
每个整数X可以除以2 log 2 (X)次,以获得非零值。因此,我们需要在每个数组元素arr [i]上执行这些log 2 (arr [i])操作,对于除法后获得的每个值,存储达到相应值所需的操作数。一次,对所有数组元素执行所有操作,对于至少K个数组元素在某个时候已减小到的每个值,在所有元素中找到所需的最小K个操作的总和。在所有此类实例中找到所需的最少操作数。
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.
请按照以下步骤使用上述方法解决问题:
- 创建一个矩阵vals [] [] ,以便vals [X] [j]将存储从数组元素获取值X所需的操作数。
- 遍历数组以及每个数组元素:
- 初始化x = arr [i]。操作CUR的初始化算作0。
- 在每一步,更新x = x / 2并将cur增加1 。将cur插入vals [x]中,作为获得x的当前值所需的除法数。
- 现在,通过将每个arr [i]重复除以2以及获得该值所需的除法次数,可以获得的所有可能值都存储在vals [] []矩阵中。
- 现在,遍历矩阵vals [] []并针对每一行执行以下操作:
- 检查当前行vals [i]是否至少包含K个元素。如果vals [i]
,则忽略,因为至少K个数组元素不能简化为i 。 - 如果瓦尔斯[I] .size()是≥K,计算行i的总和。更新ans = min(ans,vals [i]的总和) 。
- 检查当前行vals [i]是否至少包含K个元素。如果vals [i]
- 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)