思路 可以先用hashMap对每种数字出现的次数进行统计,然后再用TreeMap有排序的特性,将统计结果存到treeMap并且倒排,然后取前面k个就是我们要的数字了
public static String solution(int[] nums, int k) {
// Please write your code here
//用map记录数据
Map<Integer,Integer> map1=new HashMap<>();
//统计数字出现的次数
for (int num : nums) {
if (map1.containsKey(num)) {
map1.put(num, map1.get(num) + 1);
} else {
map1.put(num, 1);
}
}
//创建TreeMap,并让他降序排列。
TreeMap<Integer, List<Integer>> map2 = new TreeMap<>(Comparator.reverseOrder());
//根据统计数量排序,所以将key和value反过来加入treemap
map1.forEach((key,v)->{
//避免出现次数相同的数字key覆盖的情况,我们要用List存
if(map2.containsKey(v)){
map2.get(v).add(key);
}else {
List<Integer> temp=new ArrayList<>();
temp.add(key);
map2.put(v, temp);
}
});
//此时我们就得到一个降序的有序map
String str="";
List<Integer> res=new ArrayList<>();
for(List<Integer> num:map2.values()){
for (int i = 0; k>0&&i < num.size(); i++) {
k--;
/*if(k>0){
str+=num.get(i)+",";
}else{
str+=num.get(i);
}*/
res.add(num.get(i));
if(k==0){
break;
}
}
if(k==0){
break;
}
}
//题目结果是根据数字排序的
res.sort(null);
for (int i = 0; i < res.size(); i++) {
if(i!=res.size()-1){
str+=res.get(i)+",";
}else{
str+=res.get(i);
}
}
return str;
}
public static void main(String[] args) {
// You can add more test cases here
int[] nums1 = {1, 1, 1, 2, 2, 3};
int[] nums2 = {1};
int[] nums3={4,4,4,2,2,2,3,3,1};
System.out.println(solution(nums1, 2).equals("1,2"));
System.out.println(solution(nums2, 1).equals("1"));
System.out.println(solution(nums3,2).equals("2,4"));
}
解题思路
- 统计元素出现频率:首先,我们需要统计数组中每个元素的出现次数。这里我们可以使用HashMap来实现,键为元素值,值为出现次数。
- 对频率进行排序:为了找出出现频率前k高的元素,我们需要对频率进行排序。由于题目要求时间复杂度优于O(n log n),我们不能直接对HashMap进行排序。因此,我们可以使用TreeMap,它基于红黑树实现,可以保持键的有序性。
- 降序排列:我们将HashMap中的键值对反转,即将出现次数作为TreeMap的键,元素值作为值。这样,TreeMap就可以按照出现次数降序排列。这里需要特别注意出现相同次数的数字覆盖的情况,所以采用List存数据。
- 提取前k个高频元素:遍历TreeMap,取出前k个高频元素。
- 升序排列:将提取出的前k个高频元素进行升序排列。
- 返回结果:将升序排列后的元素拼接成字符串,用逗号分隔,返回结果。