mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-08-06 18:24:23 +08:00
3.8 KiB
3.8 KiB
最小化频率的删除代价
计数和排序:
- 使用 map 或 unordered_map 对数组 a 中每个元素出现的次数进行统计。
- 将统计结果存入一个 vector<pair<int, int>>,其中 pair 的第一个元素是元素的出现次数,第二个元素是元素本身。
- 按出现次数从大到小排序这个 vector。
确定最小 f(a):
- 从最大出现次数开始尝试减少 f(a)。为此,从最高频次的元素开始逐步向下考虑较少出现的元素,计算达到更低 f(a) 所需删除的元素数量。
- 使用一个累加器 count 来记录需要删除的元素数量,直到这个数量超过允许的最大删除数量 k 或恰好等于 k。在此过程中,尽量使 f(a) 达到最小。
计算达到 f(a) 的代价:
- 计算完成后,需要确定达到最小 f(a) 的确切代价。首先,为每个元素确定在不超过 k 的前提下可以删除的最大数量,以使得 f(a) 最小。
- 对于每个元素,如果它的数量超过了新的 f(a),则计算减少到 f(a) 所需删除的具体元素数,记录下来。
计算具体删除代价:
- 遍历原数组,对于每个需要删除的元素,根据其位置累加删除代价。每删除一个元素,相应地减少其在删除列表中的计数。当某元素需要删除的数量减至 0 时,从删除列表中移除该元素。
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
unordered_map<int, int> umap; // 使用map来统计每个元素的出现频率
for (int i = 0; i < n; ++i) {
umap[a[i]]++; // 统计每个元素的出现次数
}
vector<pair<int, int>> table;
for (auto& pair : umap) {
table.push_back({pair.second, pair.first}); // 将元素和其频率作为一个pair放入table中
}
sort(table.begin(), table.end(), greater<>()); // 将table按照频率从大到小排序
int count = 0; // 用来计算已经删除的元素总数
int minVal = table[0].first; // 从最高频率开始
for (int i = 0; i < table.size(); ++i) {
int freq = table[i].first;
count += (minVal - freq) * i; // 累加删除元素的代价
if (count > k) break; // 如果超过了k,停止循环
else if (count == k) {
minVal = freq;
break;
} else minVal = freq;
}
if (count < k) {
int addDel = (k - count) / table.size(); // 如果删除的代价还没达到k,计算还可以进一步减少的频率
minVal -= addDel; // 减少相应的频率
}
if (minVal < 0) {
minVal = 0; // 确保最小频率值不小于0
}
unordered_map<int, int> deleteList; // 用来存储需要删除的元素及其数量
for (auto& elem : table) {
int num = elem.first;
int ind = elem.second;
if (num > minVal) {
deleteList[ind] = num - minVal; // 如果元素频率大于最小值,计算需要删除的数量
} else {
break;
}
}
int cost = 0; // 计算总的删除代价
for (int i = 0; i < n; ++i) {
if (deleteList.find(a[i]) != deleteList.end()) {
cost += i + 1; // 删除的代价是元素的索引+1
deleteList[a[i]]--; // 删除一个元素
if (deleteList[a[i]] == 0) {
deleteList.erase(a[i]); // 如果元素已经全部删除,从列表中移除
if (deleteList.empty()) {
break; // 如果没有元素需要删除了,结束循环
}
}
}
}
cout << minVal << " " << cost << endl;
return 0;
}