Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
  • 哈希表

  • 双指针

  • 数组

  • 字符串

  • 链表

  • 树

  • 回溯

  • 动态规划

  • 图

  • 二分查找

  • 贪心

  • 栈&队列

  • 堆

    • 优先级队列
      • 215. 数组中的第K个最大元素
      • 295. 数据流的中位数
      • 347. 前 K 个高频元素
      • 373. 查找和最小的 K 对数字
      • 378. 有序矩阵中第 K 小的元素
      • 451. 根据字符出现频率排序
      • 632. 最小区间
      • 659. 分割数组为连续子序列
      • 719. 找出第 K 小的数对距离
      • 786. 第 K 个最小的素数分数
      • 264. 丑数 II
  • 位运算

  • 数据结构设计

  • rui的精选题单

  • 笔试真题

  • LeetCode周赛

  • ACM模式输入输出
  • 数学

  • 数据结构与算法
  • 堆
Nreal
2024-01-02
目录

优先级队列

# 215. 数组中的第K个最大元素 (opens new window)

方法一:堆

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();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

方法二:快排

class Solution {
    public int findKthLargest(int[] nums, int k) {
        shuffle(nums);
        int l=0,r=nums.length-1;
        k = nums.length-k;
        while(l<=r){
            int p = partition(nums,l,r);
            if(p<k) l=p+1;
            else if(p>k) r=p-1;
            else return nums[p];
        }
        return -1;
    }
    int partition(int[] nums,int l,int r){
        int i = l;
        int base = nums[r];
        for(int j=l;j<r;j++){
            if(nums[j]<base){
                swap(nums,i,j);
                i++;
            }
        }
        swap(nums,i,r);
        return i;
    }
    void shuffle(int[] nums){
        Random random = new Random();
        int n = nums.length;
        for(int i=0;i<n;i++){
            int r = i+random.nextInt(n-i);
            swap(nums,i,r);
        }
    }
    void swap(int[] nums,int l,int r){
        int tmp = nums[l];
        nums[l] = nums[r];
        nums[r] = tmp;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 295. 数据流的中位数 (opens new window)

class MedianFinder {
    PriorityQueue<Integer> large;
    PriorityQueue<Integer> small;
    public MedianFinder() {
        this.large = new PriorityQueue<>();
        this.small = new PriorityQueue<>((a,b)->{
            return b-a;
        });
    }
    public void addNum(int num) {
        if(large.isEmpty() || num>=large.peek())
            large.add(num);
        else
            small.add(num);
        modifyTwoHeapSize();
    }
    public double findMedian() {
        int largeSize = large.size();
        int smallSize = small.size();
        Integer largeHead = large.peek();
        Integer smallHead = small.peek();
        if(((largeSize+smallSize)&1)==0)
            return (largeHead+smallHead)/2.0;
        return largeSize>smallSize?largeHead:smallHead;
    }
    void modifyTwoHeapSize(){
        if(large.size() == small.size()+2)
            small.offer(large.poll());
        if(small.size() == large.size()+2)
            large.offer(small.poll());
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 347. 前 K 个高频元素 (opens new window)

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<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<>((o1,o2)->{
            return o1.getValue().compareTo(o2.getValue());
        });
        for(Map.Entry<Integer,Integer> entry:map.entrySet()){
            pq.offer(entry);
            if(pq.size()>k){
                pq.poll();
            }
        }
        int[] ret = new int[k];
        for(int i=k-1;i>=0;i--){
            ret[i] = pq.poll().getKey();
        }
        return ret;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 373. 查找和最小的 K 对数字 (opens new window)

class Solution {
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        List<List<Integer>> res = new ArrayList<>();
        PriorityQueue<int[]> pq = new PriorityQueue<>((a,b)->{
            return (a[0]+a[1])-(b[0]+b[1]);
        });
        // 先将a[*]b[0]加入堆
        for(int i=0;i<nums1.length;i++){
            pq.offer(new int[]{nums1[i],nums2[0],0});
        }
        while(!pq.isEmpty() && k>0){
            int[] cur = pq.poll();
            k--;
            int idx = cur[2]+1;
            if(idx<nums2.length){
                pq.add(new int[]{cur[0],nums2[idx],idx});
            }
            res.add(List.of(cur[0],cur[1]));
        }
        return res;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 378. 有序矩阵中第 K 小的元素 (opens new window)


1

# 451. 根据字符出现频率排序 (opens new window)

class Solution {
    public String frequencySort(String s) {
        Map<Character,Integer> map = new HashMap<>();
        for(char c:s.toCharArray()){
            map.put(c,map.getOrDefault(c,0)+1);
        }
        PriorityQueue<Character> pq = new PriorityQueue<>((x,y)->{
            return map.get(y)-map.get(x);
        });
        for(char c:map.keySet()){
            pq.offer(c);
        }
        StringBuilder sb = new StringBuilder();
        while(!pq.isEmpty()){
            char k = pq.poll();
            int v = map.get(k);
            while(v-->0){
                sb.append((char)k);
            }
        }
        return sb.toString();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 632. 最小区间 (opens new window)

# 659. 分割数组为连续子序列 (opens new window)

class Solution {
    public boolean isPossible(int[] nums) {
        var map = new HashMap<Integer,PriorityQueue<Integer>>();
        for(int x:nums){
            if(!map.containsKey(x)){
                map.put(x,new PriorityQueue<Integer>());
            }
            //存在多个子序列以x−1结尾,将x加入其中最短的子序列
            if(map.containsKey(x-1)){
                int preLen = map.get(x-1).poll();
                // 将子序列+1作为x结尾的子序列长度,x-1结尾的子序列减少一个,以x结尾的子序列增加一个
                if(map.get(x-1).isEmpty()){
                    map.remove(x-1);
                }
                map.get(x).offer(preLen+1);
            }else{
                map.get(x).offer(1);
            }
        }
        var entrySet = map.entrySet();
        for(Map.Entry<Integer,PriorityQueue<Integer>> entry:entrySet){
            PriorityQueue<Integer> que = entry.getValue();
            if(que.peek()<3){
                return false;
            }
        }
        return true;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 719. 找出第 K 小的数对距离 (opens new window)

# 786. 第 K 个最小的素数分数 (opens new window)

# 264. 丑数 II (opens new window)

栈模拟
位运算

← 栈模拟 位运算→

Theme by Vdoing | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式