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;
    }
}
原文地址:https://www.cnblogs.com/yonezu/p/13431732.html