LeetCode1851. 包含每个查询的最小区间(第239场周赛第四题)

在这里插入图片描述

// 并查集 + 离散化:
// 将涉及的点映射到[0,n], 并查集中find(x)即x所在集合的祖先,表示[x, find(x)-1]已标记答案并删除,下一个未删除的点为find(x)
// 区间按长度从小到大排序,从小到大枚举,包含在区间的点的答案即为此区间长度,因此在并查集中删除这些点(p[x] = x + 1)
class Solution {
    int[] xs = new int[300010];	// 离散化后,第i个数对应的值
    int[] p = new int[300010];	// 并查集
    int[] w = new int[300010];	// 每个点的答案

    public int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
	
	// 离散化:点加入set自动去重排序,再将点依次放入map
    Set<Integer> set = new TreeSet();
    Map<Integer, Integer> map = new HashMap();

    public int[] minInterval(int[][] intervals, int[] queries) {
        for (int[] interval : intervals) {
            set.add(interval[0]);
            set.add(interval[1]);
        }
        for (int query : queries) set.add(query);
        int j = 0;
        for (int v : set) {
            map.put(v, j);
            xs[j] = v;
            j ++;
        }
        int n = j;
        // 初始化并查集和答案集
        for (int i = 0; i < n + 1; i++) {
            p[i] = i;
            w[i] = -1;
        }
        // 区间按长度从小到大排序
        Arrays.sort(intervals, (a, b) -> (a[1] - a[0] + 1) - (b[1] - b[0] + 1));
        for (int[] interval : intervals) {	// 遍历区间
            int l = interval[0], r = interval[1];
            int len = r - l + 1;	// 区间长度
            // 对应离散化后的下标
            l = map.get(l);			
            r = map.get(r);
            // 标记[l, r] 中未标记答案的点
            while(find(l) <= r) {	// 下一个未标记的点为find(l)
                l = find(l);
                p[l] = l + 1;	// 删除点l,即下一个未标记的点为l+1
                w[l] = len;
            }
        }
        int k = queries.length;
        int[] res = new int[k];
        for (int i = 0; i < k; i++) res[i] = w[map.get(queries[i])];
        return res;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值