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

📅  最后修改于: 2021-04-25 00:21:28             🧑  作者: 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)– element(l),但C’不需要包括该成本。
    因此, C’= C –(element(l + k – 1)– element(l))
  2. 现在C’表示使[l + 1,l + K – 1]范围内的所有元素等于第(l + K – 1)元素的成本。
    由于我们需要使所有元素等于第(l + K)元素而不是第(l + K – 1)元素,因此我们可以将这些k – 1个元素增加到第(l + K)元素,这样C’= C’+(k – 1)*(element(l + k)– element(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


输出:
14

时间复杂度: O(nlogn)