给定一个大小为N的数组A[ ]和两个整数K和D ,任务是计算获得至少K 个相等数组元素所需的最小操作次数。每个操作都涉及用A[i] / D替换元素A[i] 。此操作可以执行任意次。
例子:
Input: N = 5, A[ ] = {1, 2, 3, 4, 5}, K = 3, D = 2
Output: 2
Explanation:
Step 1: Replace A[3] by A[3] / D, i.e. (4 / 2) = 2. Hence, the array modifies to {1, 2, 3, 2, 5}
Step 2: Replace A[4] by A[4] / D, i.e. (5 / 2) = 2. Hence, the array modifies to {1, 2, 3, 2, 2}
Hence, the modified array has K(= 3) equal elements.
Hence, the minimum number of operations required is 2.
Input: N = 4, A[ ] = {1, 2, 3, 6}, K = 2, D = 3
Output: 1
Explanation:
Replacing A[3] by A[3] / D, i.e. (6 / 3) = 2. Hence, the array modifies to {1, 2, 3, 2}.
Hence, the modified array has K(= 2) equal elements.
Hence, the minimum number of operations required is 1.
天真的方法:
解决问题的最简单方法是生成给定数组的每个可能子集,并对该子集的所有元素执行给定操作。每个子集所需的操作数将等于子集的大小。对于每个子集,计算相等元素的数量并检查count是否等于K 。如果是这样,将 then计数与迄今为止获得的最小移动进行比较并相应地更新。最后,打印最小移动。
时间复杂度: O(2 N *N)
辅助空间: O(N)
有效的方法:
请按照以下步骤解决问题:
- 初始化一个二维向量V ,其中,行V[i] 的大小表示已经减少到 A[i] 的数组元素的数量,该行的每个元素表示被 D 对数组元素执行的除法计数获得数字i 。
- 遍历数组。对于每个元素A[i] ,继续除以D直到它减少到0 。
- 对于上述步骤中获得的 A[i] 的每个中间值,将所需的划分次数插入到V[A[i]] 中。
- 一旦对整个数组完成上述步骤,迭代数组V[] 。
- 对于每个 V[i],检查 V[i] 的大小是否≥ K (最多 K)。
- 如果V[i] ≥ K ,则表示数组中至少有K 个元素已减少到i 。对V[i] 进行排序并添加前K 个值,即使数组中的K 个元素相等所需的最小 K 个移动。
- 将K 个移动的总和与所需的最小移动进行比较并相应地更新。
- 遍历数组V[]完成后,打印最终获得的最小移动次数。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above appraoch
#include
using namespace std;
// Function to return minimum
// number of moves required
int getMinimumMoves(int n, int k, int d,
vector a)
{
int MAX = 100000;
// Stores the number of moves
// required to obtain respective
// values from the given array
vector v[MAX];
// Traverse the array
for (int i = 0; i < n; i++) {
int cnt = 0;
// Insert 0 into V[a[i]] as
// it is the initial state
v[a[i]].push_back(0);
while (a[i] > 0) {
a[i] /= d;
cnt++;
// Insert the moves required
// to obtain current a[i]
v[a[i]].push_back(cnt);
}
}
int ans = INT_MAX;
// Traverse v[] to obtain
// minimum count of moves
for (int i = 0; i < MAX; i++) {
// Check if there are at least
// K equal elements for v[i]
if (v[i].size() >= k) {
int move = 0;
sort(v[i].begin(), v[i].end());
// Add the sum of minimum K moves
for (int j = 0; j < k; j++) {
move += v[i][j];
}
// Update answer
ans = min(ans, move);
}
}
// Return the final answer
return ans;
}
// Driver Code
int main()
{
int N = 5, K = 3, D = 2;
vector A = { 1, 2, 3, 4, 5 };
cout << getMinimumMoves(N, K, D, A);
return 0;
}
Java
// Java program to implement
// the above appraoch
import java.util.*;
class GFG{
// Function to return minimum
// number of moves required
@SuppressWarnings("unchecked")
static int getMinimumMoves(int n, int k,
int d, int[] a)
{
int MAX = 100000;
// Stores the number of moves
// required to obtain respective
// values from the given array
Vector []v = new Vector[MAX];
for(int i = 0; i < v.length; i++)
v[i] = new Vector();
// Traverse the array
for(int i = 0; i < n; i++)
{
int cnt = 0;
// Insert 0 into V[a[i]] as
// it is the initial state
v[a[i]].add(0);
while (a[i] > 0)
{
a[i] /= d;
cnt++;
// Insert the moves required
// to obtain current a[i]
v[a[i]].add(cnt);
}
}
int ans = Integer.MAX_VALUE;
// Traverse v[] to obtain
// minimum count of moves
for(int i = 0; i < MAX; i++)
{
// Check if there are at least
// K equal elements for v[i]
if (v[i].size() >= k)
{
int move = 0;
Collections.sort(v[i]);
// Add the sum of minimum K moves
for(int j = 0; j < k; j++)
{
move += v[i].get(j);
}
// Update answer
ans = Math.min(ans, move);
}
}
// Return the final answer
return ans;
}
// Driver Code
public static void main(String[] args)
{
int N = 5, K = 3, D = 2;
int []A = { 1, 2, 3, 4, 5 };
System.out.print(getMinimumMoves(N, K, D, A));
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program to implement
# the above appraoch
# Function to return minimum
# number of moves required
def getMinimumMoves(n, k, d, a):
MAX = 100000
# Stores the number of moves
# required to obtain respective
# values from the given array
v = []
for i in range(MAX):
v.append([])
# Traverse the array
for i in range(n):
cnt = 0
# Insert 0 into V[a[i]] as
# it is the initial state
v[a[i]] += [0]
while(a[i] > 0):
a[i] //= d
cnt += 1
# Insert the moves required
# to obtain current a[i]
v[a[i]] += [cnt]
ans = float('inf')
# Traverse v[] to obtain
# minimum count of moves
for i in range(MAX):
# Check if there are at least
# K equal elements for v[i]
if(len(v[i]) >= k):
move = 0
v[i].sort()
# Add the sum of minimum K moves
for j in range(k):
move += v[i][j]
# Update answer
ans = min(ans, move)
# Return the final answer
return ans
# Driver Code
if __name__ == '__main__':
N = 5
K = 3
D = 2
A = [ 1, 2, 3, 4, 5 ]
# Function call
print(getMinimumMoves(N, K, D, A))
# This code is contributed by Shivam Singh
C#
// C# program to implement
// the above appraoch
using System;
using System.Collections.Generic;
class GFG{
// Function to return minimum
// number of moves required
static int getMinimumMoves(int n, int k,
int d, int[] a)
{
int MAX = 100000;
// Stores the number of moves
// required to obtain respective
// values from the given array
List []v = new List[MAX];
for(int i = 0; i < v.Length; i++)
v[i] = new List();
// Traverse the array
for(int i = 0; i < n; i++)
{
int cnt = 0;
// Insert 0 into V[a[i]] as
// it is the initial state
v[a[i]].Add(0);
while (a[i] > 0)
{
a[i] /= d;
cnt++;
// Insert the moves required
// to obtain current a[i]
v[a[i]].Add(cnt);
}
}
int ans = int.MaxValue;
// Traverse v[] to obtain
// minimum count of moves
for(int i = 0; i < MAX; i++)
{
// Check if there are at least
// K equal elements for v[i]
if (v[i].Count >= k)
{
int move = 0;
v[i].Sort();
// Add the sum of minimum K moves
for(int j = 0; j < k; j++)
{
move += v[i][j];
}
// Update answer
ans = Math.Min(ans, move);
}
}
// Return the final answer
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int N = 5, K = 3, D = 2;
int []A = { 1, 2, 3, 4, 5 };
Console.Write(getMinimumMoves(N, K, D, A));
}
}
// This code is contributed by 29AjayKumar
2
时间复杂度: O(MlogM),其中 M 是取的最大数目
辅助空间: O(M)