久违的掉大分
【模拟】出现最频繁的偶数元素
题目
给你一个整数数组 nums
,返回出现最频繁的偶数元素。
如果存在多个满足条件的元素,只需要返回 最小 的一个。如果不存在这样的元素,返回 -1
。
示例 1:
|
|
示例 2:
|
|
示例 3:
|
|
提示:
1 <= nums.length <= 2000
0 <= nums[i] <= 10^5
解题思路
按题意模拟即可
代码
|
|
【贪心】子字符串的最优划分
题目
给你一个字符串 s
,请你将该字符串划分成一个或多个 子字符串 ,并满足每个子字符串中的字符都是 唯一 的。也就是说,在单个子字符串中,字母的出现次数都不超过 一次 。
满足题目要求的情况下,返回 最少 需要划分多少个子字符串*。*
注意,划分后,原字符串中的每个字符都应该恰好属于一个子字符串。
示例 1:
|
|
示例 2:
|
|
提示:
1 <= s.length <= 10^5
s
仅由小写英文字母组成
解题思路
每次出现重复字母时再新起一个划分
代码
|
|
【二分/贪心+优先队列/差分数组】将区间分为最少组数
题目
给你一个二维整数数组 intervals
,其中 intervals[i] = [lefti, righti]
表示 闭 区间 [lefti, righti]
。
你需要将 intervals
划分为一个或者多个区间 组 ,每个区间 只 属于一个组,且同一个组中任意两个区间 不相交 。
请你返回 最少 需要划分成多少个组。
如果两个区间覆盖的范围有重叠(即至少有一个公共数字),那么我们称这两个区间是 相交 的。比方说区间 [1, 5]
和 [5, 8]
相交。
示例 1:
|
|
示例 2:
|
|
提示:
1 <= intervals.length <= 10^5
intervals[i].length == 2
1 <= lefti <= righti <= 10^6
解题思路
经典贪心。但是没印象。
赛时用的二分。将区间排序(第一维升序,第二维升序),考虑划分成k个组是否ok。对于第i个区间,在k个组中找到第一个结尾最小且不冲突的区间,若不存在则不ok,若存在,则将第i个区间放在该组后面。
一开始想错了,还以为这个也能二分,最后就是二分套二分,但很显然不是,然后想到了用线段树维护每个组的最小结尾,并记录相应的id。
然后还RE了一发,是因为自定义排序那儿,手误把a[1]<b[1]打成了b[0]<b[1]。
其实,这根本用不到二分,按上面的想,如果不存在合法的组,直接新建一个组即可。
更进一步,直接用一个优先队列维护即可。
另外一种思路是转换成上下车模型,每个区间看成一个人,他在 left 时刻上车,right+1 时刻下车,最后答案为同时在车上的人数的最大值。这可以用差分数组实现
代码
二分
|
|
优先队列
|
|
差分
|
|
【线段树优化DP】最长递增子序列 II
题目
给你一个整数数组 nums
和一个整数 k
。
找到 nums
中满足以下要求的最长子序列:
- 子序列 严格递增
- 子序列中相邻元素的差值 不超过
k
。
请你返回满足上述要求的 最长子序列 的长度。
子序列 是从一个数组中删除部分元素后,剩余元素不改变顺序得到的数组。
示例 1:
|
|
示例 2:
|
|
示例 3:
|
|
提示:
1 <= nums.length <= 10^5
1 <= nums[i], k <= 10^5
解题思路
普通LIS的常规解法是$O(n^2)$的dp,有一种$O(n\ logn)$的解法是基于二分的dp。
碰到这题往二分那种思路想了,即dp[i]表示长度为i的最小元素,结果没整出来
赛后才了解到,还能用线段树实现$O(n\ logn)$复杂度的普通LIS。
对于这题,令dp[i][j]表示前i个数且末尾元素为j的合法LIS的最长长度,
那么以j结尾的合法LIS的前一个数字的值域应在[j-k, j-1]范围内 dp[i][j] = max{ dp[i-1][j-k…j-1] }+1,
第一维可以省略
利用线段树维护这个dp数组
代码
|
|