Day 03| 215数组中的第K个最大元素&347前 K 个高频元素

66 阅读1分钟

数组中的第K个最大元素 Leetcode 215

思路

可以把小顶堆 pq 理解成一个筛子,较大的元素会沉淀下去,较小的元素会浮上来;当堆大小超过 k 的时候,我们就删掉堆顶的元素,因为这些元素比较小,而我们想要的是前 k 个最大元素嘛。

PriorityQueue 被用来实现一个最小堆,用于查找整数数组中的第 k 大元素。每次向堆中插入元素后,如果堆的大小超过了 k,则移除堆顶元素,保持堆的大小为 k。最终,堆顶元素即为第 k 大元素。

二叉堆:

class Solution {
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        for(int num:nums){
            pq.offer(num);
            if(pq.size()>k){
                pq.poll();
            }
        }
        return pq.peek();
    }
}

也可以实现O(n)的时间复杂度

class Solution {
    public int findKthLargest(int[] nums, int k) {
        return quickSelect(nums, 0, nums.length - 1, nums.length - k);
    }
    
    private int quickSelect(int[] nums, int left, int right, int targetIndex) {
        if (left == right) return nums[targetIndex];
        
        int pivot = nums[left];
        int i = left, j = right;
        
        while (i < j) {
            while (i < j && nums[j] >= pivot) j--;
            if (i < j) nums[i++] = nums[j];
            
            while (i < j && nums[i] <= pivot) i++;
            if (i < j) nums[j--] = nums[i];
        }
        
        nums[i] = pivot;
        
        if (targetIndex <= i) return quickSelect(nums, left, i, targetIndex);
        else return quickSelect(nums, i + 1, right, targetIndex);
    }
}

Leetcode 347 前 K 个高频元素

思路

和之前215一致,使用PriorityQueue做,只是结合了HashMap

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        HashMap<Integer,Integer> map = new HashMap<>();
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        PriorityQueue<Map.Entry<Integer,Integer>>
            pq = new PriorityQueue<>((entry1,entry2)->{return entry1.getValue().compareTo(entry2.getValue());
        });
        for(Map.Entry<Integer,Integer> entry:map.entrySet()){
            pq.offer(entry);
            if(pq.size()>k){
                pq.poll();
            }
        }
        int[] res = new int[k];
        for(int i=k-1;i>=0;i--){
            res[i]=pq.poll().getKey();
        }
        return res;
    }
}