查找热点数据问题 | 豆包MarsCode AI刷题

57 阅读2分钟

思路 可以先用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"));
}

解题思路

  1. 统计元素出现频率:首先,我们需要统计数组中每个元素的出现次数。这里我们可以使用HashMap来实现,键为元素值,值为出现次数。
  2. 对频率进行排序:为了找出出现频率前k高的元素,我们需要对频率进行排序。由于题目要求时间复杂度优于O(n log n),我们不能直接对HashMap进行排序。因此,我们可以使用TreeMap,它基于红黑树实现,可以保持键的有序性。
  3. 降序排列:我们将HashMap中的键值对反转,即将出现次数作为TreeMap的键,元素值作为值。这样,TreeMap就可以按照出现次数降序排列。这里需要特别注意出现相同次数的数字覆盖的情况,所以采用List存数据。
  4. 提取前k个高频元素:遍历TreeMap,取出前k个高频元素。
  5. 升序排列:将提取出的前k个高频元素进行升序排列。
  6. 返回结果:将升序排列后的元素拼接成字符串,用逗号分隔,返回结果。