数组大小减半
难度:
标签:
题目描述
代码结果
运行时间: 60 ms, 内存: 32.4 MB
/*
* 思路:
* 1. 使用Java Stream计算每个元素的频次。
* 2. 频次降序排序。
* 3. 累加最高频次的元素直到覆盖数组的一半。
* 4. 返回最小集合的大小。
*/
import java.util.*;
import java.util.stream.Collectors;
public class Solution {
public int minSetSize(int[] arr) {
Map<Integer, Long> frequencyMap = Arrays.stream(arr)
.boxed()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()));
List<Long> frequencies = frequencyMap.values().stream()
.sorted(Collections.reverseOrder())
.collect(Collectors.toList());
long removed = 0, halfSize = arr.length / 2;
int setSize = 0;
for (long freq : frequencies) {
removed += freq;
setSize++;
if (removed >= halfSize) break;
}
return setSize;
}
}
解释
方法:
该题目的核心是找到一个最小的整数集合,使得从数组中删除这些整数后,数组的大小至少减少一半。首先,我们使用 Counter 类来统计数组中每个整数的出现频次。接着,将得到的频次进行降序排序。这样,选择频次最高的数,我们可以更快地减少数组的大小。我们从频次最高的元素开始,逐个累加这些元素的出现次数,直到这个累加值达到或超过原数组长度的一半。此时,累加的元素个数就是所需的最小集合大小。
时间复杂度:
O(n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在解法中,为什么要选择将频次进行降序排序而不是升序或保持原有顺序?
▷🦆
算法中提到的`累加频次`是否能确保在最坏情况下仍然能够找到满足条件的最小集合?
▷🦆
如果数组中包含重复元素的数量刚好等于数组长度的一半,算法的输出会是什么?
▷🦆
给定`sorted_counts`列表,如果中间某个频次巨大,足以单独满足减半条件,算法是否有机制优化以避免不必要的累加操作?
▷