632. 最小区间

你有 k 个 非递减排列 的整数列表。找到一个 最小 区间,使得 k 个列表中的每个列表至少有一个数包含在其中。

我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区间 [a,b] 比 [c,d] 小。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/smallest-range-covering-elements-from-k-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

import java.util.*;

class Solution {
    public int[] smallestRange(List<List<Integer>> nums) {
        if (nums == null || nums.size() == 0) {
            return new int[0];
        }

        PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return Integer.compare(nums.get(o1[0]).get(o1[1]), nums.get(o2[0]).get(o2[1]));
            }
        });
        int minLength = Integer.MAX_VALUE, minLeft = -1, minRight = -1, curMax = Integer.MIN_VALUE;

        for (int i = 0; i < nums.size(); ++i) {
            curMax = Math.max(curMax, nums.get(i).get(0));
            queue.offer(new int[]{i, 0});
        }

        while (queue.size() == nums.size()) {
            int[] node = queue.poll();
            int x = node[0], y = node[1], data = nums.get(x).get(y);
            if (curMax - data < minLength) {
                minLength = curMax - data;
                minLeft = data;
                minRight = curMax;
            }

            if (y + 1 < nums.get(x).size()) {
                curMax = Math.max(curMax, nums.get(x).get(y + 1));
                queue.offer(new int[]{x, y + 1});
            }
        }

        return new int[]{minLeft, minRight};
    }
}

滑动窗口

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class Solution {
    public int[] smallestRange(List<List<Integer>> nums) {
        int size = nums.size();
        Map<Integer, List<Integer>> indices = new HashMap<Integer, List<Integer>>();
        int xMin = Integer.MAX_VALUE, xMax = Integer.MIN_VALUE;
        for (int i = 0; i < size; i++) {
            for (int x : nums.get(i)) {
                List<Integer> list = indices.getOrDefault(x, new ArrayList<Integer>());
                list.add(i);
                indices.put(x, list);
                xMin = Math.min(xMin, x);
                xMax = Math.max(xMax, x);
            }
        }

        int[] freq = new int[size];
        int inside = 0;
        int left = xMin, right = xMin - 1;
        int bestLeft = xMin, bestRight = xMax;

        while (right < xMax) {
            right++;
            if (indices.containsKey(right)) {
                for (int x : indices.get(right)) {
                    freq[x]++;
                    if (freq[x] == 1) {
                        inside++;
                    }
                }
                while (inside == size) {
                    if (right - left < bestRight - bestLeft) {
                        bestLeft = left;
                        bestRight = right;
                    }
                    if (indices.containsKey(left)) {
                        for (int x : indices.get(left)) {
                            freq[x]--;
                            if (freq[x] == 0) {
                                inside--;
                            }
                        }
                    }
                    left++;
                }
            }
        }

        return new int[]{bestLeft, bestRight};
    }
}
posted @ 2021-12-15 23:01  Tianyiya  阅读(39)  评论(0)    收藏  举报