347前K个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

// class Solution {
//     public int[] topKFrequent(int[] nums, int k) {
//         // 排序
//         // 
//         int n = nums.length;
//         int[] ans = new int[n - k + 1];
//         int idx = 0;
//         Arrays.sort(nums);
//         for(int i = 0; i < n; i++){
//             int num = nums[i];
//             int cnt = 1;
//             int j = i + 1;
//             while(j < n && num == nums[j]) {
//                 cnt++;
//                 if(cnt >= k) {
//                     ans[idx++] = num;
//                     break;
//                 }
//                 j++;
//             }
//             i = j;
//         }
//         return ans;
//     }
// }

// 左右指针
// class Solution{
//     public int[] topKFrequent(int[] nums, int k){
//         int n = nums.length;
//         List<Integer> list = new ArrayList<>();
//         // int[] ans = new int[n];
//         Arrays.sort(nums);
//         int l = 0, r = 0;
//         int idx = 0;
//         while(r < n){
//             int cnt = 0;
//             while(r < n && nums[l] == nums[r]){
//                 cnt++;
//                 r++;
//             }
//             if(cnt >= k){
//                 // ans[idx++] = nums[l];
//                 list.add(nums[l]);
//             }
//             l = r;

//         }
//         int[] ans = new int[list.size()];
//         for(int num : list) ans[idx++] = num;
//         // Integer[] ans = (int)list.toArray(new Integer[list.size()]);
//         return ans;
//     }
// }

// 理解错题意了。。。靠



// HashMap
// class Solution{
//     public int[] topKFrequent(int[] nums, int k){
        
//         // 使用map统计nums
//         Map<Integer, Integer> map = new HashMap<>();
//         for(int num : nums){
//             if(map.containsKey(num)){
//                 map.put(num, map.get(num) + 1);
//             } else {
//                 map.put(num, 1);
//             }
//         }
//         // 
//         int[] ans = new int[k];
//         int idx = 0;
//         for(int i = 0; i < k; i++){
//             int max = Integer.MIN_VALUE;
//             // 遍历map
//             int num = -1;
//             for(Map.Entry<Integer, Integer> entry : map.entrySet()){
//                 if(entry.getValue() > max) {
//                     num = entry.getKey();
//                     max = entry.getValue();
//                 }
//             }
//             map.remove(num);
//             ans[idx++] = num;
//         }
//         return ans;
//     }
// }

// 
class Solution{
    public int[] topKFrequent(int[] nums, int k){
        int n = nums.length;
        Map<Integer, Integer> map = new HashMap<>();
        for(int num : nums){
            // if(map.containsKey(num)) map.put(num, map.get(num) + 1);
            // else map.put(num, 1);
            map.put(num, map.getOrDefault(num, 0) + 1);
        }
        // 我妄想用数组,代替桶。
        // 再出现重复频率的数字情况,不能在一个数组位置存储多个元素
        /*
        int[] numss = new int[n + 1];
        for(Map.Entry<Integer, Integer> entrySet : map.entrySet()){
            numss[entrySet.getValue()] = entrySet.getKey();
        }
        int[] ans = new int[k];
        int idx = n;
        for(int i = 0; i < k; i++){
            while(numss[idx] == 0) idx--;
            ans[i] = numss[idx--]; 
        }
        return ans;
        */
        // list类型的数组
        List<Integer>[] list = new List[n + 1];
        // 将value对应的下标,添加上key
        for(Map.Entry<Integer, Integer> entrySet : map.entrySet()){
            int idx = entrySet.getValue();
            // 不判断是否为null就创建的话,可能会重复覆盖创建
            if(list[idx] == null) list[idx] = new ArrayList();
            list[idx].add(entrySet.getKey());
        }
        // // 从后向前,将list取出k个
        // int[] ans = new int[k];
        // for(i = 0; i < k; i++){

        // }
        List<Integer> ans = new ArrayList<>();
        for(int i = n; i >= 0 && ans.size() < k; i--){
            if(list[i] == null) continue;
            ans.addAll(list[i]);
        }
        // int[] arr = ans.toArray();
        return ans.stream().mapToInt(Integer::intValue).toArray();
    }
}

优先队列,大顶堆、小顶堆。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值