C++ 中如何从数组中移除最少元素,使最大值 – 最小值 <= K

c++server side programmingprogramming

问题描述

给定 N 个整数和 K 个元素,求出需要移除的最小元素数,使得 Amax - Amin <= K。移除元素后,剩余元素中将包含 Amax 和 Amin。

示例

如果 arr[] = {1, 3, 4, 9, 10, 11, 12, 17, 20} 且 k = 4,则输出为 5:

  • 从数组开头移除 1、3 和 4
  • 从数组末尾移除 17 和 20
  • 最终数组变为 {9, 10, 11, 12},其中 12 – 9 <= 4

算法

1. 对给定元素进行排序
2. 使用贪婪算法,最佳方法是移除最小元素或最大元素,然后检查 Amax - Amin 是否 <= K。移除元素的组合有很多种,需要考虑。
3. 移除元素有两种可能的方式:移除最小元素或移除最大元素。令 (i…j) 为移除元素后剩余元素的索引。初始时 i=0,j=n-1,移除元素个数为 0。
4. 仅当 a[j]-a[i]>k 时才移除元素,两种可能的移除方式是 (i+1…j) 或 (i…j-1)。取两者中较小的一个。

示例

#include <bits/stdc++.h>
#define MAX 100
using namespace std;
int dp[MAX][MAX];
int removeCombinations(int *arr, int i, int j, int k) {
   if (i >= j) {
   return 0;
   } else if ((arr[j] - arr[i]) <= k) {
      return 0;
   } else if (dp[i][j] != -1) {
      return dp[i][j];
   } else if ((arr[j] - arr[i]) > k) {
      dp[i][j] = 1 + min(removeCombinations(arr, i +
      1, j, k),
      removeCombinations(arr, i, j - 1,k));
   }
   return dp[i][j];
}
int removeNumbers(int *arr, int n, int k){
   sort(arr, arr + n);
   memset(dp, -1, sizeof(dp));
   return n == 1 ? 0 : removeCombinations(arr, 0, n - 1,k);
}
int main() {
   int arr[] = {1, 3, 4, 9, 10, 11, 12, 17, 20};
   int n = sizeof(arr) / sizeof(arr[0]);
   int k = 4;
   cout << "Minimum numbers to be removed = " <<
   removeNumbers(arr, n, k) << endl;
   return 0;
}

编译并执行上述程序,将生成以下输出

输出

Minimum numbers to be removed = 5

相关文章