📌  相关文章
📜  最小化除以D的次数以获得至少K个相等的数组元素

📅  最后修改于: 2021-04-25 00:24:40             🧑  作者: Mango

给定大小为N的数组A []以及两个整数KD ,任务是计算获得至少K个相等数组元素所需的最小可能操作数。每个操作都涉及用A [i] / D替换元素A [i] 。此操作可以执行任意次。

例子:

天真的方法:
解决该问题的最简单方法是生成给定数组的每个可能子集,然后对该子集的所有元素执行给定操作。每个子集所需的操作数将等于子集的大小。对于每个子集,计算相等元素的数量,然后检查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)