leetcode biweekly contest 87
leetcode biweekly contest 87
今天周赛的题目质量还算蛮高,最后一题很少出线段树的模板题目了
6176. 出现最频繁的偶数元素
题目
给你一个整数数组 nums ,返回出现最频繁的偶数元素。
如果存在多个满足条件的元素,只需要返回 最小 的一个。如果不存在这样的元素,返回 -1 。
示例 1:
1 | |
示例 2:
1 | |
示例 3:
1 | |
提示:
1 <= nums.length <= 20000 <= nums[i] <= 105
地址
https://leetcode.cn/problems/most-frequent-even-element/
题意
哈希统计
思路
- 直接统计偶数元素的个数,并求出出现次数最多的偶数。
- 复杂度分析:
- 时间复杂度:$O(n)$,其中 $n$ 表示数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 表示数组的长度。
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Solution {
public:
int mostFrequentEven(vector<int>& nums) {
map<int,int> cnt;
for (auto v : nums) {
if (v % 2 == 0) {
cnt[v]++;
}
}
int ans = -1, freq = 0;
for (auto [x, f] : cnt) {
if (f > freq) {
ans = x;
freq = f;
}
}
return ans;
}
};
6177. 子字符串的最优划分
题目
给你一个字符串 s ,请你将该字符串划分成一个或多个 子字符串 ,并满足每个子字符串中的字符都是 唯一 的。也就是说,在单个子字符串中,字母的出现次数都不超过 一次 。
满足题目要求的情况下,返回 最少 需要划分多少个子字符串。
注意,划分后,原字符串中的每个字符都应该恰好属于一个子字符串。
示例 1:
1 | |
示例 2:
1 | |
提示:
1 <= s.length <= 105s仅由小写英文字母组成
地址
https://leetcode.cn/problems/optimal-partition-of-string/
题意
贪心 + 直接遍历
思路
- 感觉没啥好说的,直接切分即可,遍历到字符出现多次的情形,则进行切分。根据贪心理论,两个相同的字符一定不能出现在不同的
- 复杂度分析:
- 时间复杂度:时间复杂度为 $O(n)$,$n$ 表示字符串的长度。
- 空间复杂度:空间复杂度为 $O(|\Sigma|)$,$|\Sigma|$ 表示字符集的大小。
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Solution {
public:
int partitionString(string s) {
vector<int> cnt(26);
int ans = 1;
for (int i = 0; i < s.size(); i++) {
if (cnt[s[i] - 'a'] == 0) {
cnt[s[i] - 'a']++;
} else {
cnt = vector<int>(26);
ans++;
cnt[s[i] - 'a']++;
}
}
return ans;
}
};
6178. 将区间分为最少组数
题目
给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示 闭 区间 [lefti, righti] 。
你需要将 intervals 划分为一个或者多个区间 组 ,每个区间 只 属于一个组,且同一个组中任意两个区间 不相交 。
请你返回 最少 需要划分成多少个组。
如果两个区间覆盖的范围有重叠(即至少有一个公共数字),那么我们称这两个区间是 相交 的。比方说区间 [1, 5] 和 [5, 8] 相交。
示例 1:
1 | |
示例 2:
1 | |
提示:
1 <= intervals.length <= 105intervals[i].length == 21 <= lefti <= righti <= 106
地址
https://leetcode.cn/problems/divide-intervals-into-minimum-number-of-groups/
题意
查分数组
思路
- 本体与某个
CPU调度的题目基本上一模一样的原理,本质上就是求区间中最大的重叠次数即可,只需要求出最大重叠此时一定可以划分为不同的区间。 - 复杂度分析
- 时间复杂度:时间复杂度为 $O(n \log n)$,$n$ 为数组的长度。
- 空间复杂度:空间复杂度为 $O(n)$,$n$ 为数组的长度。
代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Solution {
public:
int minGroups(vector<vector<int>>& intervals) {
map<int, int> cnt;
for (auto v : intervals) {
cnt[v[0]]++;
cnt[v[1] + 1]--;
}
int curr = 0, ans = 0;
for (auto [_, x] : cnt) {
curr += x;
ans = max(ans, curr);
}
return ans;
}
};
6206. 最长递增子序列 II
题目
给你一个整数数组 nums 和一个整数 k 。
找到 nums 中满足以下要求的最长子序列:
- 子序列 严格递增
- 子序列中相邻元素的差值 不超过
k。
请你返回满足上述要求的 最长子序列 的长度。
子序列 是从一个数组中删除部分元素后,剩余元素不改变顺序得到的数组。
示例 1:
1 | |
示例 2:
1 | |
示例 3:
1 | |
提示:
1 <= nums.length <= 1051 <= nums[i], k <= 105
地址
https://leetcode.cn/problems/longest-increasing-subsequence-ii/
题意
线段树模板
思路
- 典型的线段树模板,我们设 $dp[i]$ 表示以 $i$ 为结尾的元素所能构成最长子序列,对于当前的元素 $x$,我们需要查询以区间 $[x-k,x -1]$ 中的元素为结尾的最长递增子序列的长度,即我们需要查询 $dp[x-k, \cdots, x -1]$ 这样元素的最大值 $maxVal$,同时将 $dp[x] = maxVal + 1$,可以得到递推公式如下:所以很容易采用线段树来进行范围查询和范围更新,非常典型的线段树模板题目。方法二维动态开点的线段树模板。
- 复杂度分析:
- 时间复杂度:$O(n \log \max(nums))$,其中 $n$ 表示数组的长度,$\max(nums)$ 表示数组中的最大元素。
- 空间复杂度:$O(\max(nums))$,$\max(nums)$ 表示数组中的最大元素。
代码
1 | |
1 | |
#
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://mikemeng.org/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
