LeetCode1338:数组大小减半
给你一个整数数组 arr。你可以从中选出一个整数集合,并删除这些整数在数组中的每次出现。
返回 至少 能删除数组中的一半整数的整数集合的最小大小。
示例 1:
输入: arr = [3,3,3,3,5,5,5,2,2,7]
输出: 2
解释: 选择 {3,7} 使得结果数组为 [5,5,5,2,2]、长度为 5(原数组长度的一半)。
大小为 2 的可行集合有 {3,5},{3,2},{5,2}。
选择 {2,7} 是不可行的,它的结果数组为 [3,3,3,3,5,5,5],新数组长度大于原数组的二分之一。
示例 2:
输入: arr = [7,7,7,7,7,7]
输出: 1
解释: 我们只能选择集合 {7},结果数组为空。
提示:
arr.length为偶数
思路分析
先使用哈希表对数组各个元素的数量进行统计,我们不关心数组各个元素具体是多少,只关心各个元素出现的次数,将次数存入一个数组ar中,对该数组进行排序。从大到小进行遍历,当移除的元素个数之和大于等于数组元素个数的一半时,即完成任务,返回移除数字的种数。
- 1.用哈希映射map记录每个整数出现的数目
- 2.再从哈希映射map中将整数的数目存入数组num中
- 3.将数组num进行排序
- 4.用原数组arr的数目不断减去最大的数目(用ans'每减一次记录一次),直至小于或等于原数组大小的一半返回ans即可
算法代码
public int minSetSize(int[] arr) {
//哈希
HashMap < Integer, Integer > map = new HashMap < > (); //记录各个整数出现的次数
int len = arr.length;
for (int i = 0; i < len; i++) {
map.put(arr[i], map.getOrDefault(arr[i], 0) + 1);
}
int size = map.size();
int[] num = new int[size];
int f = 0;
for (int n: map.values()) { //将各个整数的数目记录在num数组中
num[f++] = n;
}
int ans = 0;
Arrays.sort(num); //排序
for (int i = size - 1; i >= 0; i--) { //从数目大的开始减(因为找最小·步数
if (len > arr.length / 2) //目前数组数目仍大于一半
{
len -= num[i];
ans++;
} else break;
}
return ans;
}
结果详情
算法复杂度
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN)一起进步,一起成长!