• leetcode (堆->hard) 23,218,239,295,407,786


    23 合并K个升序链表

       首先最简单的当然是建个堆往里面加,优点是基本不需要思考。。。

    public static ListNode mergeKLists(ListNode[] lists) {
            PriorityQueue<ListNode> pq = new PriorityQueue<>((k1,k2)->k2.val-k1.val);
            for (int i = 0; i < lists.length; i++) {
                ListNode node  = lists[i];
                while (node != null){
                    pq.add(node);
                    node = node.next;
                }
            }
            if (pq.isEmpty())return null;
            ListNode poll = new ListNode(pq.poll().val);
            while (!pq.isEmpty()){
                ListNode poll1 = pq.poll();
                poll1.next = poll;
                poll = poll1;
            }
            return poll;
        }

      然后应该这种合并序列的方式应该也是可以使用N指针的方式 堆只需要维护lists.size()大小

    public static ListNode mergeKLists(ListNode[] lists) {
    
            if (lists == null || lists.length == 0){
                return null;
            }
            PriorityQueue<ListNode> pq = new PriorityQueue<>((k1,k2)->k1.val-k2.val);
            for (ListNode listNode : lists) {
                if (listNode == null)continue;
                pq.add(listNode);
            }
            if (pq.isEmpty()){
                return null;
            }
            ListNode poll = pq.poll();
            if (poll.next != null){
                pq.add(poll.next);
            }
            ListNode tp = poll;
            while (!pq.isEmpty()){
                ListNode current = pq.poll();
                if (current.next != null){
                    pq.add(current.next);
                }
                tp.next = current;
                tp = tp.next;
            }
            return poll;
        }

    218 这题自己真的是毫无头绪,看到的大佬的扫描法感觉是相当的厉害,也是看了好久才明白 点击  传送门 

       使用扫描法来解

      public static List<List<Integer>> getSkyline(int[][] buildings) {
            List<List<Integer>> result = new ArrayList<>();
            PriorityQueue<int[]> pq = new PriorityQueue<>((k1,k2)-> k1[0] == k2[0] ? k1[1]-k2[1]:k1[0]-k2[0]);
            for (int[] building : buildings) {
                pq.add(new int[]{building[0],-building[2]});
                pq.add(new int[]{building[1],building[2]});
            }
    
            int maxHeight = 0;
            TreeMap<Integer,Integer> treeMap = new TreeMap<>((k1,k2)->k2-k1);
            treeMap.put(0,1);
            while (!pq.isEmpty()){
                int[] value = pq.poll();
                int x = value[0];
                int val = value[1];
                if (val < 0){
                    //左端点  高度入tree
                    treeMap.put(-val,treeMap.getOrDefault(-val,0)+1);
                }else {
                    //右端点
                    Integer count = treeMap.get(val);
                    if (count == 1){
                        treeMap.remove(val);
                    }else {
                        treeMap.put(val,--count);
                    }
                }
                Integer currentMax = treeMap.keySet().iterator().next();
                if (!currentMax.equals(maxHeight)){
                    maxHeight = currentMax;
                    result.add(Arrays.asList(x,maxHeight));
                }
            }
            return result;
    
        }

    239 滑动窗口最大值

       这个我的思路是用堆来维护,然后每遍历一个值的时候找到堆顶,如果堆顶的元素在滑动窗口内就是正确答案,如果不是就poll继续找。

            if (k == 1)return nums;
            int[] arr = new int[nums.length-k+1];
            PriorityQueue<Integer> pq = new PriorityQueue<>((k1,k2)->nums[k2]-nums[k1]);
            int s = 0;
            for (int i = 0; i < nums.length; i++) {
                pq.add(i);
                if (i >= k-1){
                    while (pq.peek() < i+1-k){
                        pq.poll();
                    }
                    arr[s++] = nums[pq.peek()];
                }
            }
            return arr;

      当然了 一顿操作猛如虎,一看击败百分五

    295 中位数

      这题按理说是要设计一个数据结构  既要快速找到中位数,又要满足快速的插入新的节点。想法是实现类似一个平衡树,但是太复杂了没实现了。。。 然后通用的思路是双堆法

        PriorityQueue<Integer> big;
        PriorityQueue<Integer> small;
        int size;
        public HeapSimple14() {
            big = new PriorityQueue<>((k1,k2)->k1-k2);
            small = new PriorityQueue<>((k1,k2)->k2-k1);
        }
    
        public void addNum(int num) {
            size++;
            if ((size &1) != 0){
                big.offer(num);
            }else {
                small.offer(num);
            }
            swap();
        }
        private void swap(){
            if (!big.isEmpty() && !small.isEmpty()){
                while (big.peek() < small.peek()  ){
                    Integer bigP = big.poll();
                    Integer smallP = small.poll();
                    big.offer(smallP);
                    small.offer(bigP);
                }
            }
        }
        public double findMedian() {
            if ((size & 1) == 1){
                return big.peek();
            }
            return (double)(big.peek()+small.peek())/2;
        }

    407  接雨水2

      这特么还有三维接雨水的,不知道后面会不会出四维五维。。。

       感觉有点难 先放着

    786 第k个最小素数分数

      用堆一阵暴力解决

       public static int[] kthSmallestPrimeFraction(int[] arr, int k) {
            PriorityQueue<int[]> pq = new PriorityQueue<>((k1,k2)-> {
                double a = (double) k1[0]/k1[1];
                double b= (double) k2[0]/k2[1];
                if (a == b){
                    return 0;
                }else if (a >b){
                    return -1;
                }else {
                    return 1;
                }
            });
            for (int i = arr.length-1; i >=0 ; i--) {
                for (int j = 0; j < i; j++) {
                    if (pq.size() <k){
                        pq.add(new int[]{arr[j],arr[i]});
                    }else {
                        int[] peek = pq.peek();
                        if ((double) arr[j]/arr[i] < (double) peek[0]/peek[1] ){
                            pq.poll();
                            pq.add(new int[]{arr[j],arr[i]});
                        }else {
                            break;
                        }
                    }
                }
            }
            
            
            return pq.poll();
    
        }

      堆系列继续耻辱结束。。。

  • 相关阅读:
    SICP学习笔记(1.3.4)
    SICP学习笔记(1.1.7 ~ 1.1.8)
    It's Not Just Standing Up: Patterns of Daily Standup Meetings
    SICP学习笔记(1.1.4~1.1.5)
    SICP学习笔记(2.1.4)
    呵呵呵,传说中的吉普赛读心术(WPF版)
    利用SendMessage实现窗口拖动
    SICP学习笔记(2.2.2)
    SICP学习笔记(2.3.1~2.3.2)
    SICP学习笔记(2.3.3)
  • 原文地址:https://www.cnblogs.com/hetutu-5238/p/14362778.html
Copyright © 2020-2023  润新知