• 632. 最小区间(滑动窗口,优先队列)


     方法一:滑动窗口

    class Solution {
        public int[] smallestRange(List<List<Integer>> nums) {
            int size = nums.size();
            Map<Integer,List<Integer>> map = new HashMap<>();
            int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
            for(int i = 0; i < size; i++) {
                for(int num : nums.get(i)) {
                    map.computeIfAbsent(num,k->new ArrayList<>()).add(i);
                    min = Math.min(min,num);
                    max = Math.max(max,num);
                }
            }
            int[] pos = new int[size];
            int left = min, right = min;
            int l = min, r = max;
            int count = 0; // 窗口覆盖区间个数
            while(right <= max) {
                if(map.containsKey(right)) {
                    for(int p : map.get(right)) {
                        if(pos[p]++ == 0) count++;
                    }
                    while(count == size) {
                        if(right - left < r - l) {
                            r = right;
                            l = left;
                        }
                        if(map.containsKey(left)) {
                            for(int p : map.get(left)) {
                                if(--pos[p] == 0) count--;
                            }
                        }
                        left++;
                    }
    
                }
                right++;
            }
            return new int[]{l,r};
        }
    }

    方法二:优先队列

    class Solution {
        public int[] smallestRange(List<List<Integer>> nums) {
            int n = nums.size(), max = Integer.MIN_VALUE;
            int[] res = new int[]{Integer.MIN_VALUE/3,Integer.MAX_VALUE/3};
            PriorityQueue<int[]> queue = new PriorityQueue<>((o1,o2)->(o1[0]-o2[0]));// 保存每个区间的最小值,区间编号,区间索引
            for(int i = 0; i < n; i++) { // 初始化优先队列
                List<Integer> list = nums.get(i);
                int[] val = new int[]{list.get(0),i,0};
                queue.add(val);
                max = Math.max(max,list.get(0));
            }
            while(true) {
                int[] q = queue.poll();
                if(max - q[0] < res[1] - res[0]) {
                    res[1] = max;
                    res[0] = q[0];
                }
                int index = ++q[2];
                if(index >= nums.get(q[1]).size()) break; // 指针越界就退出
                int[] newQ = new int[]{nums.get(q[1]).get(index),q[1],index};
                queue.add(newQ);
                max = Math.max(max,nums.get(q[1]).get(index)); // 更新最大值
            }
            return res;
        }
    }
  • 相关阅读:
    工作中的体悟和经验
    java中List的toArray方法
    Arthas干货总结
    内部类访问外部类的方法
    PriorityBlockingQueue 源码分析
    ArrayBlockingQueue 源码解析
    Kafka 读书笔记--日志索引
    Mybatis源码解析之--谈谈${}
    Mybatis源码分析之--浅析ResultSetHandler
    linux命令--ll
  • 原文地址:https://www.cnblogs.com/yonezu/p/13431732.html
Copyright © 2020-2023  润新知