前言
本场周赛,博主也只写出两道题(前两道, hhh菜鸡勿喷),第三道涉及位运算 ,数位dp,第四道涉及KMP。 下面我们来总结一下这四道题。
正文
1.3005. 最大频率元素计数
这道题不难,不过有一个比较妙的写法,因此还是来分析总结一下。
- 题目链接: 最大频率元素计数
- 题目思路:
- 用一个unordered_map更新次数。
- 更新出最大次数时,也更新ans的初始值。
- 当等于最大次数时,对ans 加上 当前最大次数。
- 关键:最大次数的出现是呈现递增趋势的.
- 因此我们可以
一边记录unordered_map, 一边更新最大次数和answer。并且一个循环就可以更新出结果。
class Solution {
public:
int maxFrequencyElements(vector<int>& nums)
{
int max_cnt = 0;
int ans = 0;
unordered_map<int,int> hash;
for(auto e : nums)
{
if(++hash[e] > max_cnt)
max_cnt = ans = hash[e];
else if(hash[e] == max_cnt)
ans += max_cnt;
}
return ans;
}
};
2.3007.价值和小于等于 K 的最大数字
-
题目链接:价值和小于等于 K 的最大数字
-
题目大思路:【数位dp】 / 【分类讨论 + 数学分析】 + 二分
- 数位dp
- 从高位开始枚举,一直枚举到最低位。
- 下一位的枚举的数字范围收到上一位的约束。
- 对不受到上一位约束的,采取记忆化的策略。受到上一位约束的,只有一种情况,无需记忆化。
- 实现代码:
class Solution {
public:
long long findMaximumNumber(long long k, int x)
{
//数位dp
auto check = [&](long long num)
{
//找其中为1 - num 上 x 的整数倍上 为 1的个数。
//1.先将num转换为二进制数,到最高位即可。
string s;
for(int i = 0; i < 64; i++)
{
if(num & (1ll << (63 - i)))
s += "1";
else
s += "0";
}
long long dp[64][64];
memset(dp,-1ll,sizeof(dp));
/*
其中dp表示为枚举第 i 位,之前之前已经有j个1时,数字出现1的总数
1.limit表示第i位是否收到约束,即只能枚举 0 ~ s[i] - '0',
如果收到,下一位也要收到约束,否则可以枚举 0 ~ 9
2.如果枚举第i位没收到约束,且之前j个1已经求过,则无需再求,
即记忆化。反之,只会出现一次,没必要记忆化,当然记忆化也可以。
*/
function<long long(int,int,bool)> dfs = [&](

最低0.47元/天 解锁文章
3040

被折叠的 条评论
为什么被折叠?



