📌  相关文章
📜  使 K 个元素相等的最小增量操作

📅  最后修改于: 2021-10-26 06:35:42             🧑  作者: Mango

给定一个由N 个元素组成的数组arr[]和一个整数K ,任务是通过只执行递增操作来使数组中的任何K 个元素相等,即在一次操作中,任何元素都可以递增 1。找到最少的操作次数需要使任何K 个元素相等。
例子:

幼稚的方法:

  1. 按升序对数组进行排序。
  2. 现在选择K 个元素并使它们相等。
  3. 选择第i值作为最大值,并使所有小于它的元素等于第i元素。
  4. 计算使所有i 的K 个元素等于第i元素所需的操作数。
  5. 答案将是所有可能性中的最小值。

这种方法的时间复杂度为O(n*K + nlogn)
有效的方法:天真的方法可以用给定的恒定时间的滑动窗口技术进行修改,以计算使K个元素所需的最小操作等于i元素比O(K)快于用于制造第所需的操作与第K元素相等的元素是已知的。
C为使范围[l, l + K – 1] 中的元素等于第(l + K – 1)元素所需的操作或成本。现在要找到范围[l + 1, l + K]的成本,可以使用范围[l, l + K – 1]的解决方案。
C’[l + 1, l + K]范围的成本。

  1. 由于我们将l元素递增到第(l + K – 1)元素,因此C包括成本元素 (l + k – 1) – 元素 (l) 但C’不需要包括此成本。
    所以, C’ = C – (元素(l + k – 1) – 元素(l))
  2. 现在C’表示使[l + 1, l + K – 1]范围内的所有元素等于第(l + K – 1)元素的成本。
    因为,我们需要使所有元素等于第(l + K)元素而不是第(l + K – 1)元素,我们可以将这些k – 1 个元素递增到第(l + K)元素,这使得C’ = C’ + (k – 1) * (元素(l + k) – 元素(l + k -1))

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the minimum number of
// increment operations required to make
// any k elements of the array equal
int minOperations(vector ar, int k)
{
    // Sort the array in increasing order
    sort(ar.begin(), ar.end());
 
    // Calculate the number of operations
    // needed to make 1st k elements equal to
    // the kth element i.e. the 1st window
    int opsNeeded = 0;
    for (int i = 0; i < k; i++) {
        opsNeeded += ar[k - 1] - ar[i];
    }
 
    // Answer will be the minimum of all
    // possible k sized windows
    int ans = opsNeeded;
 
    // Find the operations needed to make
    // k elements equal to ith element
    for (int i = k; i < ar.size(); i++) {
 
        // Slide the window to the right and
        // subtract increments spent on leftmost
        // element of the previous window
        opsNeeded = opsNeeded - (ar[i - 1] - ar[i - k]);
 
        // Add increments needed to make the 1st k-1
        // elements of this window equal to the
        // kth element of the current window
        opsNeeded += (k - 1) * (ar[i] - ar[i - 1]);
        ans = min(ans, opsNeeded);
    }
    return ans;
}
 
// Driver code
int main()
{
    vector arr = { 3, 1, 9, 100 };
    int n = arr.size();
    int k = 3;
 
    cout << minOperations(arr, k);
 
    return 0;
}


Java
// Java implementation of the approach
import java.util.Arrays;
 
class geeksforgeeks {
 
// Function to return the minimum number of
// increment operations required to make
// any k elements of the array equal
static int minOperations(int ar[], int k)
{
    // Sort the array in increasing order
    Arrays.sort(ar);
 
    // Calculate the number of operations
    // needed to make 1st k elements equal to
    // the kth element i.e. the 1st window
    int opsNeeded = 0;
    for (int i = 0; i < k; i++) {
        opsNeeded += ar[k - 1] - ar[i];
    }
 
    // Answer will be the minimum of all
    // possible k sized windows
    int ans = opsNeeded;
 
    // Find the operations needed to make
    // k elements equal to ith element
    for (int i = k; i < ar.length; i++) {
 
        // Slide the window to the right and
        // subtract increments spent on leftmost
        // element of the previous window
        opsNeeded = opsNeeded - (ar[i - 1] - ar[i - k]);
 
        // Add increments needed to make the 1st k-1
        // elements of this window equal to the
        // kth element of the current window
        opsNeeded += (k - 1) * (ar[i] - ar[i - 1]);
        ans = Math.min(ans, opsNeeded);
    }
    return ans;
}
 
// Driver code
public static void main(String[] args)
{
    int[] arr = { 3, 1, 9, 100 };
    int n = arr.length;
    int k = 3;
 
    System.out.printf("%d",minOperations(arr, k));
}
}
 
// This code is contributed by Atul_kumar_Shrivastava


Python3
# Python3 implementation of the approach
 
# Function to return the minimum number of
# increment operations required to make
# any k elements of the array equal
def minOperations(ar, k):
 
    # Sort the array in increasing order
    ar = sorted(ar)
 
    # Calculate the number of operations
    # needed to make 1st k elements equal to
    # the kth element i.e. the 1st window
    opsNeeded = 0
    for i in range(k):
        opsNeeded += ar[k - 1] - ar[i]
 
    # Answer will be the minimum of all
    # possible k sized windows
    ans = opsNeeded
 
    # Find the operations needed to make
    # k elements equal to ith element
    for i in range(k, len(ar)):
 
        # Slide the window to the right and
        # subtract increments spent on leftmost
        # element of the previous window
        opsNeeded = opsNeeded - (ar[i - 1] - ar[i - k])
 
        # Add increments needed to make the 1st k-1
        # elements of this window equal to the
        # kth element of the current window
        opsNeeded += (k - 1) * (ar[i] - ar[i - 1])
        ans = min(ans, opsNeeded)
 
    return ans
 
# Driver code
arr = [3, 1, 9, 100]
n = len(arr)
k = 3
 
print(minOperations(arr, k))
 
# This code is contributed by Mohit Kumar


C#
// C# implementation of the approach
using System;
 
class geeksforgeeks {
 
// Function to return the minimum number of
// increment operations required to make
// any k elements of the array equal
static int minOperations(int[] ar, int k)
{
    // Sort the array in increasing order
    Array.Sort(ar);
 
    // Calculate the number of operations
    // needed to make 1st k elements equal to
    // the kth element i.e. the 1st window
    int opsNeeded = 0;
    for (int i = 0; i < k; i++) {
        opsNeeded += ar[k - 1] - ar[i];
    }
 
    // Answer will be the minimum of all
    // possible k sized windows
    int ans = opsNeeded;
 
    // Find the operations needed to make
    // k elements equal to ith element
    for (int i = k; i < ar.Length; i++) {
 
        // Slide the window to the right and
        // subtract increments spent on leftmost
        // element of the previous window
        opsNeeded = opsNeeded - (ar[i - 1] - ar[i - k]);
 
        // Add increments needed to make the 1st k-1
        // elements of this window equal to the
        // kth element of the current window
        opsNeeded += (k - 1) * (ar[i] - ar[i - 1]);
        ans = Math.Min(ans, opsNeeded);
    }
    return ans;
}
 
// Driver code
public static void Main()
{
    int[] arr = { 3, 1, 9, 100 };
    int n = arr.Length;
    int k = 3;
 
    Console.Write(minOperations(arr, k));
}
}
 
// This code is contributed by AbhiThakur


Javascript


输出:
14

时间复杂度: O(nlogn)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程