这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情
问题描述
给你一个整数数组 arr 和一个整数 k 。现需要从数组中恰好移除 k 个元素,请找出移除后数组中不同整数的最少数目。
示例 1:
输入:arr = [5,5,4], k = 1
输出:1
解释:移除 1 个 4 ,数组中只剩下 5 一种整数。
示例 2:
输入:arr = [4,3,1,1,3,3,2], k = 3
输出:2
解释:先移除 4、2 ,然后再移除两个 1 中的任意 1 个或者三个 3 中的任意 1 个,最后剩下 1 和 3 两种整数。
提示:
- 1 <= arr.length <= 10^5
- 1 <= arr[i] <= 10^9
- 0 <= k <= arr.length
思路分析
首先我们先要理解一下题目意思,题目会给我们一个数组arr和一个整数k,我们需要从数组中恰好移除 k 个元素,并且使得移除 k 个元素后的数组中不重复的元素数量最少。
理解了题意之后我们便可以开始进行解题了,我们只要思考怎样移除可以使得数组汇总不重复的元素数量最少即可,要使移除 k 个元素后数组中元素种类最少的话,我们应该要尽可能的保证移除的元素种类最多,而要使得移除的元素种类最多的话,我们需要优先将数组中重复元素数量最少的移除,所以我们可以通过以下步骤进行解题:
- 1、统计数组中各元素出现的次数
使用哈希表对数组中各元素出现的测试进行统计
const map = {};
for (const num of arr) {
map[num] = (map[num] || 0) + 1;
}
- 2、将元素按出现次数多少进行排序
将所有出现过的元素按照前面统计的出现次数进行排序。
const list = [...Object.keys(map)];
list.sort((a, b) => {
return map[b] - map[a];
});
- 3、计算最多可以移除多少种元素
每次移除一种类的元素后,我们需要将k减少对应元素的数量,k小于等于0时则说明移除机会已经用完。
let res = list.length;
while (list.length && k > 0) {
const num = map[list[res - 1]];
k -= num;
if (k >= 0) res--;
}
完整 AC 代码如下:
AC 代码
/**
* @param {number[]} arr
* @param {number} k
* @return {number}
*/
var findLeastNumOfUniqueInts = function (arr, k) {
const map = {};
for (const num of arr) {
map[num] = (map[num] || 0) + 1;
}
const list = [...Object.keys(map)];
list.sort((a, b) => {
return map[b] - map[a];
});
let res = list.length;
while (list.length && k > 0) {
const num = map[list[res - 1]];
k -= num;
if (k >= 0) res--;
}
return res;
};
说在后面
本人为算法业余爱好者,平时只是随着兴趣偶尔刷刷题,如果上面分享有错误的地方,欢迎指出,一定改正,感激不尽。