LeetCode—310场周赛(前三题)
一.6176. 出现最频繁的偶数元素(哈希表)
题目内容:
给你一个整数数组
nums
,返回出现最频繁的偶数元素。如果存在多个满足条件的元素,只需要返回 最小 的一个。如果不存在这样的元素,返回
-1
。
思路:
- 先找到数组里的偶数元素,再将该元素的对应的出现次数存入哈希表中
- 在哈希表中查询出现次数最多的元素即可
代码:
class Solution {
public:
int mostFrequentEven(vector<int>& nums) {
map<int,int> m;
for(auto &i : nums){
if(i%2==0)
m[i]++;
}
int ans=-1;
int count=0;
for(auto &it : m){
if(it.second>count)
{
count=it.second;
ans=it.first;
}
}
return ans;
}
};
二.6177. 子字符串的最优划分(哈希表+贪心)
题目内容:
给你一个字符串 s ,请你将该字符串划分成一个或多个 子字符串 ,并满足每个子字符串中的字符都是 唯一 的。也就是说,在单个子字符串中,字母的出现次数都不超过 一次 。
满足题目要求的情况下,返回 最少 需要划分多少个子字符串。
注意,划分后,原字符串中的每个字符都应该恰好属于一个子字符串。
- 示例:
输入:s = “abacaba”
输出:4
解释:
两种可行的划分方法分别是 (“a”,“ba”,“cab”,“a”) 和 (“ab”,“a”,“ca”,“ba”) 。
可以证明最少需要划分 4 个子字符串。
思路:
- 贪心思路:要求子字符串最少,那么对于每个子字符串就想更长
- 将子字符串的存入哈希表,如该键值已经存在则刷新哈希表
代码
class Solution {
public:
int mostFrequentEven(vector<int>& nums) {
map<int,int> m;
for(auto &i : nums){
if(i%2==0)
m[i]++;
}
int ans=-1;
int count=0;
for(auto &it : m){
if(it.second>count)
{
count=it.second;
ans=it.first;
}
}
return ans;
}
};
三.6178. 将区间分为最少组数(贪心)
题目说明:
给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示 闭 区间 [lefti, righti] 。
你需要将 intervals 划分为一个或者多个区间 组 ,每个区间 只 属于一个组,且同一个组中任意两个区间 不相交 。
请你返回 最少 需要划分成多少个组。
如果两个区间覆盖的范围有重叠(即至少有一个公共数字),那么我们称这两个区间是 相交 的。比方说区间 [1, 5] 和 [5, 8] 相交。
示例:
输入:intervals = [[5,10],[6,8],[1,5],[2,3],[1,10]]
输出:3
解释:我们可以将区间划分为如下的区间组:
- 第 1 组:[1, 5] ,[6, 8] 。
- 第 2 组:[2, 3] ,[5, 10] 。
- 第 3 组:[1, 10] 。
可以证明无法将区间划分为少于 3 个组。
思路:
经典的贪心类型题:区间图着色
- 很多时候对于区间的题我们都可以选择贪心来做,因为区间上点总是具有单调性它很容易保证我们做出相对最优的选择
- 最少需要划分成多少个组换个说法为寻找最多有多少个不相交的部分(如图),然后用总的减去不相交的部分
贪心思维:
- 要想划分的组更少,那么最好能有更多的不相交的组,为了能获得更多的不相交的组,那么右端点越小越好,这样留给左端点不在目前右端点之内的空间更大——即我们每次都选择更小的右端点
- 在右端点以左的左端点必定和该区间相交
思路:
- 我们将左右端点分别按照升序排序
- 每次都选取最小的右端点,这样在小于它的左端点必然发生相交
- 当左端点遍历完成,即对于整个数据所包含的区间范围全部遍历一次
- 每当我们发现有不会相交即左端点大于当前右端点时,我们才会去找下一个左端点,也就是说从end[0]以后j每走一次代表找到了一次不相交(可以着同色)的情况(正好和下标相对应)
- 最后用总的减去不相交的部分
代码:
class Solution {
public:
int minGroups(vector<vector<int>>& a) {
vector<int> start,end;
for(auto &i : a){
start.push_back(i[0]);
end.push_back(i[1]);
}
sort(start.begin(),start.end());
sort(end.begin(),end.end());
int i=0;
int j=0;
while(i<start.size())
{
if(start[i]>end[j])
j++;
i++;
}
return start.size()-j;
}
};