第一次AK力扣周赛,上大分了。继上次双周赛刷新最好名次后,周赛再度刷新。
【模拟】移除字母异位词后的结果数组
题目
给你一个下标从 0 开始的字符串 words
,其中 words[i]
由小写英文字符组成。
在一步操作中,需要选出任一下标 i
,从 words
中 删除 words[i]
。其中下标 i
需要同时满足下述两个条件:
0 < i < words.length
words[i - 1]
和words[i]
是 字母异位词 。
只要可以选出满足条件的下标,就一直执行这个操作。
在执行所有操作后,返回 words
。可以证明,按任意顺序为每步操作选择下标都会得到相同的结果。
字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。例如,"dacb"
是 "abdc"
的一个字母异位词。
示例 1:
|
|
示例 2:
|
|
提示:
1 <= words.length <= 100
1 <= words[i].length <= 10
words[i]
由小写英文字母组成
解题思路
按题意模拟即可
代码
|
|
【排序】不含特殊楼层的最大连续楼层数
题目
Alice 管理着一家公司,并租用大楼的部分楼层作为办公空间。Alice 决定将一些楼层作为 特殊楼层 ,仅用于放松。
给你两个整数 bottom
和 top
,表示 Alice 租用了从 bottom
到 top
(含 bottom
和 top
在内)的所有楼层。另给你一个整数数组 special
,其中 special[i]
表示 Alice 指定用于放松的特殊楼层。
返回不含特殊楼层的 最大 连续楼层数。
示例 1:
|
|
示例 2:
|
|
提示
1 <= special.length <= 10^5
1 <= bottom <= special[i] <= top <= 10^9
special
中的所有值 互不相同
解题思路
将special数组排序后,遍历一遍找最大连续层数即可
代码
|
|
【枚举】按位与结果大于零的最长组合
题目
对数组 nums
执行 按位与 相当于对数组 nums
中的所有整数执行 按位与 。
- 例如,对
nums = [1, 5, 3]
来说,按位与等于1 & 5 & 3 = 1
。 - 同样,对
nums = [7]
而言,按位与等于7
。
给你一个正整数数组 candidates
。计算 candidates
中的数字每种组合下 按位与 的结果。 candidates
中的每个数字在每种组合中只能使用 一次 。
返回按位与结果大于 0
的 最长 组合的长度*。*
示例 1:
|
|
示例 2:
|
|
提示:
1 <= candidates.length <= 10^5
1 <= candidates[i] <= 10^7
解题思路
看完题后第一时间还没想好思路,但看了下一开始通过率高的吓人,就冷静下来想了一下
如果考虑每一种数字组合的话,复杂度会过高,不可能的。换个角度想
按位与结果最后要大于0,说明它们的与运算结果的二进制表示中至少有1位不能为0
由于数的范围是10^7,没有超过int,那么最多可以考虑32位,枚举每一位,使得该位不为0,为了数字组合长度最长,只要不使得该位按位与运算后变为0,那么可以尽量的将数字选进来。
代码
|
|
【动态开点线段树】统计区间中的整数数目
题目
给你区间的 空 集,请你设计并实现满足要求的数据结构:
- 新增:添加一个区间到这个区间集合中。
- 统计:计算出现在 至少一个 区间中的整数个数。
实现 CountIntervals
类:
CountIntervals()
使用区间的空集初始化对象void add(int left, int right)
添加区间[left, right]
到区间集合之中。int count()
返回出现在 至少一个 区间中的整数个数。
注意:区间 [left, right]
表示满足 left <= x <= right
的所有整数 x
。
示例 1:
|
|
提示:
1 <= left <= right <= 10^9
- 最多调用
add
和count
方法 总计10^5
次 - 调用
count
方法至少一次
动态开点线段树
读完题就鉴定为可以用线段树做。
由于值域范围达10^9,但询问次数为10^5,所以采用动态开点线段树
节点维护区间中整数数目即可。
本来代码很快就码好了,但是忽略了对tot,root的初始化,并且一开始将它们放在了类里面,造成了奇奇怪怪的错误。找了好久才发现,然后将它们移到类外,并进行显示初始化。(如果不进行显示初始化是不行的,力扣可能会测试多组用例,后面再初始化需要重置才行)。
|
|
模拟 求区间并集
求区间并集模板题。用一个 set 有序地维护所有不相交的区间,当加入区间 [left, right] 时,通过 lower_bound 快速找到第一个右端点大于等于 left - 1 的区间,然后不断用接下来的区间和 [left, right] 合并,直到当前区间的左端点大于 right + 1。由于每个区间只会加入以及离开 set 一次,复杂度O(nlogn)。
|
|