11.堆

23--合并k个升序的链表

public ListNode mergeKLists(ListNode[] lists) {
        if(lists==null||lists.length==0)return null;
        PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>() {
            @Override
            public int compare(ListNode l1, ListNode l2) {
                return l1.val - l2.val;
            }
        });

        for (int i = 0; i < lists.length; i++) {
            ListNode now=lists[i];
            while (now!=null){
                pq.offer(now);
                now=now.next;
            }
        }
        ListNode last;
        ListNode res;
        //注意链表可能全是空的
        if(pq.size()>=1){
            last = pq.poll();
            res =last;
        }else{
            return null;
        }

        while (!pq.isEmpty()) {
            ListNode poll = pq.poll();
            last.next=poll;
            last=poll;
        }
        last.next=null;
        return res;
    }

218--天际线问题

    public List<List<Integer>> getSkyline(int[][] bs) {
        List<List<Integer>> ans = new ArrayList<>();

        // 预处理所有的点,为了方便排序,对于左端点,令高度为负;对于右端点令高度为正
        List<int[]> ps = new ArrayList<>();
        for (int[] b : bs) {
            int l = b[0], r = b[1], h = b[2];
            ps.add(new int[]{l, -h});
            ps.add(new int[]{r, h});
        }

        // 先按照横坐标进行排序
        // 如果相同的左/右端点,则按照高度进行排序
        Collections.sort(ps, (a, b)->{
            if (a[0] != b[0]) return a[0] - b[0];
            return a[1] - b[1];
        });

        // 大根堆
        PriorityQueue<Integer> q = new PriorityQueue<>((a,b)->b-a);
        int prev = 0;//最下面的点是一定会被取到的
        q.add(prev);
        for (int[] p : ps) {
            int point = p[0], height = p[1];
            if (height < 0) {
                // 如果是左端点,说明存在一条往右延伸的可记录的边,将高度存入优先队列
                q.add(-height);
            } else {
                // 如果是右端点,说明这条边结束了,将当前高度从队列中移除
                q.remove(height);
            }

            // 取出最高高度,如果当前不与前一矩形“上边”延展而来的那些边重合,则可以被记录
            int cur = q.peek();
            if (cur != prev) {
                List<Integer> list = new ArrayList<>();
                list.add(point);
                list.add(cur);
                ans.add(list);
                prev = cur;
            }
        }
        return ans;
    }

239--滑动窗口的最大值

 public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> {
            return a[0]!=b[0]?b[0]-a[0]:b[1]-a[1];
        });
        for (int i = 0; i < k; i++) {
            //元素 索引
            pq.offer(new int[]{nums[i],i});
        }
        int[] ans=new int[n-k+1];
        ans[0]=pq.peek()[0];
        for (int i = k; i <n ; i++) {
            pq.offer(new int[]{nums[i],i});
            //如果当前最大值的索引已经超出了滑动窗口的左边界,丢出去再也不要了
            while (pq.peek()[1]<=i-k){
                pq.poll();
            }
            ans[i-k+1]=pq.peek()[0];
        }
        return ans;
    }

264--数据流的中位数

    PriorityQueue<Integer> min;
    PriorityQueue<Integer> max;

    public likou295() {
        min = new PriorityQueue<>((a,b)->b-a);
        max = new PriorityQueue<>();
    }

    public void addNum(int num) {
        if(min.isEmpty()||num<=min.peek()){
            min.offer(num);
            //当大队列数小于小队列数2个以上的时候,从小队列补充元素
            if(max.size()+1<min.size()){
                max.offer(min.poll());
            }
        }else{
            max.offer(num);
            //只要小队列的size比大队列的size小就补充元素,这样保证了小队列永远大于等于大队列
            if(max.size()>min.size()){
                min.offer(max.poll());
            }
        }
    }

    public double findMedian() {
        if(min.size()>max.size())return min.peek();
        else{
            return  (min.peek()+max.peek())/2.0;
        }
    }

 347--前k个高频元素

 public int[] topKFrequent(int[] nums, int k) {
        PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>((a,b)->b.getValue()-a.getValue());
        int[] res=new int[k];
        HashMap<Integer, Integer> map = new HashMap<>();
        //使用哈希表计数
        for (int i = 0; i < nums.length; i++) {
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
        }
        //遍历哈希表
        Iterator<Map.Entry<Integer, Integer>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()){
            queue.offer(iterator.next());
        }
        int count=0;
        while (count!=k){
            Map.Entry<Integer, Integer> poll = queue.poll();
            res[count]=poll.getKey();
            count++;
        }
        return res;
    }

373--查找和最小的k对数字

public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        //大顶堆
        PriorityQueue<List<Integer>> queue = new PriorityQueue<>(k, (o1, o2)->{
            return (o2.get(0) + o2.get(1)) - (o1.get(0) + o1.get(1));
        });
        //取最小值是为了防止两个数组一个比较少的时候【1】  【1,2,3】
        for(int i = 0; i < Math.min(nums1.length, k); i++){
            for(int j = 0; j < Math.min(nums2.length, k); j++){
                if(queue.size() < k) {
                    List<Integer> pair = new ArrayList<>();
                    pair.add(nums1[i]);
                    pair.add(nums2[j]);
                    queue.add(pair);
                }else {
                    int top = queue.peek().get(0) + queue.peek().get(1);
                    //大于K就出队列
                    if(top > nums1[i]+nums2[j]){
                        List<Integer> pair = new ArrayList<>();
                        queue.poll();
                        pair.add(nums1[i]);
                        pair.add(nums2[j]);
                        queue.add(pair);
                    }
                }
            }
        }
        List<List<Integer>> res = new LinkedList<>();
        for(int i =0; i < k && !queue.isEmpty(); i++){
            res.add(queue.poll());
        }
        return res;
    }

 378--有序矩阵中第k小的元素

 public int kthSmallest(int[][] matrix, int k) {
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        int l = matrix[0].length;
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < l; j++) {
                queue.offer(matrix[i][j]);
            }
        }
        int res=Integer.MAX_VALUE;
        while (k!=0){
            res=queue.poll();
            k--;
        }
        return res;
    }

658--找到k个最接近的元素

public List<Integer> findClosestElements(int[] arr, int k, int x) {
        PriorityQueue<Integer> queue = new PriorityQueue<>((a,b)->{
            return Math.abs(a-x)==Math.abs(b-x)?a-b:Math.abs(a-x)-Math.abs(b-x);
        });

        for (int i : arr) {
            queue.offer(i);
        }
        List<Integer> res=new ArrayList<>();
        while (k--!=0&&!queue.isEmpty()){
            res.add(queue.poll());
        }
        Collections.sort(res);
        return res;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值