385.小C的mex查询 题解及思路
385.小C的mex查询
问题描述
题目描述如下:
小C拿到了一个空集。她准备进行以下操作:将
[l,r]区间的每个整数添加进集合。每次操作后,输出当前集合的
mex。定义集合的mex为:集合中最小的未出现的非负整数。
示例1:
输入:q = 4,queries = [[1, 3], [7, 8], [0, 5], [3, 6]]
输出:[0, 0, 6, 9]
解释:
1.集合为[1,3],集合中最小的未出现的非负整数为0;
2.集合更新为[[1,3],[7,8]],集合中最小的未出现的非负整数仍为0;
3.集合更新为[[0,5],[7,8]],集合中最小的未出现的非负整数为6;
4.集合更新为[0,8],集合中最小的未出现的非负整数为9;
示例2:
输入:q = 3,queries = [[0, 2], [3, 4], [6, 10]]
输出:[3, 5, 5]
解释:
1.集合为[0,2],集合中最小的未出现的非负整数为3;
2.集合更新为[0,4],集合中最小的未出现的非负整数为5;
3.集合更新为[[0,4],[6,10]],集合中最小的未出现的非负整数为5;
示例3:
输入:q = 2,queries = [[2, 5], [7, 9]]
输出:[0, 0]
解释:
1.集合为[2,5],集合中最小的未出现的非负整数为0;
2.集合更新为[[2,5],[7,9]],集合中最小的未出现的非负整数仍为0;
解题思路
思路1
创建了一个 HashMap<Integer, Integer> 类型的 count 变量,用于统计每个整数在区间内出现的次数。
创建了一个长度为 q的 result 数组,用于存储最终每个区间对应的未出现的最小整数结果。
初始化了一个变量 min,初始值为 0,用于后续查找每个区间内未出现的最小整数。
先进行一个判断,如果当前记录的最小未出现整数 min 大于区间的结束值,说明这个区间内不存在比 min 更小的未出现整数了,那么直接将 min 赋值给 result[i],并跳过循环
循环遍历[l,r] 区间的每个整数,加到count 中,完成一个区间内整数的计数后,通过一个 while 循环来查找该区间内未出现的最小整数。只要 count 这个 HashMap 中包含当前的 min,就将 min 的值加 1,不断查找下一个整数,直到找到一个在区间内未出现过的整数
java代码
public static int[] solution(int q, int[][] queries) {
// write code here
Map<Integer,Integer> count = new HashMap<>();
int[] result= new int[q];
int min = 0;
for (int i = 0; i < q; i++) {
if (min > queries[i][1]) {
result[i] = min;
continue;
}
for (int j = queries[i][0]; j <= queries[i][1]; j++) {
count.put(j, count.getOrDefault(j, 0)+1);
}
while (count.containsKey(min)) {
min++;
}
result[i]= min;
}
return result; // Placeholder
}
思路2
使用BitSet集合类
依然先判断当前记录的最小未出现整数 min 是否大于区间的结束值
循环遍历区间,通过 set 方法标记整数是否出现过
通过 nextClearBit 方法快速找到下一个未出现的整数位置
java代码
public static int[] solution(int q, int[][] queries) {
BitSet appeared = new BitSet();
int[] result = new int[q];
for (int i = 0; i < q; i++) {
if ( i>0 && result[i-1] > queries[i][1]) {
result[i] = result[i-1];
continue;
}
for (int j = queries[i][0]; j <= queries[i][1]; j++) {
appeared.set(j);
}
int k = appeared.nextClearBit(0);
result[i] = k;
}
return result;
}