给你一个整数数组 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},结果数组为空。
示例 3:
输入:arr = [1,9] 输出:1
示例 4:
输入:arr = [1000,1000,3,7] 输出:1
示例 5:
输入:arr = [1,2,3,4,5,6,7,8,9,10] 输出:5
提示:
1 <= arr.length <= 105
arr.length 为偶数
1 <= arr[i] <= 105来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reduce-array-size-to-the-half
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这个超时了
public class Solution1338 {
public int minSetSize(int[] arr) {
int length = arr.length / 2;
int count = 0;
HashMap<Integer,Integer> hashMap = new HashMap<>();
HashSet<Integer> hashSet = new HashSet<>();
for(int i:arr){
hashSet.add(i);
hashMap.put(i,hashMap.containsKey(i)?hashMap.get(i)+1:1);
}
while(length>=0){
int max = 0;
int maxNum = 0;
for(int i : hashSet){
if(hashMap.get(i)>max){
max = hashMap.get(i);
maxNum = i;
}
}
hashSet.remove(maxNum);
length -= max;
count++;
}
return count;
}
}
优先队列(大顶堆)
public class Solution1338_1 {
public int minSetSize(int[] arr) {
Arrays.sort(arr);
int count = 0;
PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
if(o1 < o2){
return 1;
}else if(o1 == o2){
return 0;
}else{
return -1;
}
}
});
int length = arr.length;
int sum = 0;
for(int i = 0;i < length;i++){
if(i+1==length || arr[i] != arr[i+1]){
queue.add(sum+1);
sum = 0;
}else{
sum++;
}
}
int len = length / 2;
while(len > 0){
len -= queue.poll();
count++;
}
return count;
}
}
用一个数组记录每个数字出现的次数
class Solution {
public int minSetSize(int[] arr) {
int[] count = new int[100000];
Arrays.fill(count,0);
for(int i : arr){
count[i-1]++;
}
Arrays.sort(count);
int n = 99999;
int length = arr.length/2;
while(length > 0){
length -= count[n];
n--;
}
return 99999-n;
}
}