【上分日记】第380场周赛(数位dp+ KMP + 位运算 + 二分 + 双指针 )

文章目录

  • 前言
  • 正文
    • 1.3005. 最大频率元素计数
    • 2.3007.价值和小于等于 K 的最大数字
    • 3.3008. 找出数组中的美丽下标 II
  • 总结
  • 尾序

前言

 本场周赛,博主也只写出两道题(前两道, hhh菜鸡勿喷),第三道涉及位运算 ,数位dp,第四道涉及KMP。 下面我们来总结一下这四道题。

正文

1.3005. 最大频率元素计数

 这道题不难,不过有一个比较妙的写法,因此还是来分析总结一下。

  • 题目链接: 最大频率元素计数
  • 题目思路:
  1. 用一个unordered_map更新次数。
  2. 更新出最大次数时,也更新ans的初始值。
  3. 当等于最大次数时,对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】 / 【分类讨论 + 数学分析】 + 二分

  1. 数位dp
  1. 从高位开始枚举,一直枚举到最低位。
  2. 下一位的枚举的数字范围收到上一位的约束。
  3. 对不受到上一位约束的,采取记忆化的策略。受到上一位约束的,只有一种情况,无需记忆化。
  • 实现代码:
class Solution {
public:long long findMaximumNumber(long long k, int x) {//数位dpauto 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";elses += "0";}long long dp[64][64];memset(dp,-1ll,sizeof(dp));/*其中dp表示为枚举第 i 位,之前之前已经有j个1时,数字出现1的总数1.limit表示第i位是否收到约束,即只能枚举 0 ~ s[i] - '0',如果收到,下一位也要收到约束,否则可以枚举 0 ~ 92.如果枚举第i位没收到约束,且之前j个1已经求过,则无需再求,即记忆化。反之,只会出现一次,没必要记忆化,当然记忆化也可以。*/function<long long(int,int,bool)> dfs = [&](int i ,\long long j,bool limit){if(i == 64) return j;else if(!limit && dp[i][j] != -1) return dp[i][j];long long res = 0;int end = limit ? s[i] - '0' : 1;for(int m = 0;  m <= end; m++){res += dfs(i+1,j + (m == 1 && (64 - i) % x == 0),\limit && (m == end));/*m == 1 且是x的倍数成立,结果位 j + 1,反之为 j如果当前位受到限制,且枚举之后的n也达到了end,则下一位受到限制。*/}if(!limit) dp[i][j] = res;return res;};return dfs(0,0,true);};//二分long long left = 0,right = k << x;//找靠近右边最大的num,因此要固定右边枚举左边。while(left < right){long long mid = (left + right + 1) / 2;if(check(mid) > k)right = mid - 1;elseleft = mid;}//必然会有答案。return left;}
};

说明:模版题——233. 数字 1 的个数

  1. 位运算 + 分类讨论
    在这里插入图片描述
class Solution {
public:long long findMaximumNumber(long long k, int x) {//位运算 + 分类讨论auto check = [&](long long num){long long ans = 0;int cnt = x - 1;for(long long i = num >> cnt; i; cnt += x,i >>= x){ans += (i / 2) << cnt;if(i % 2){long long mask = (1ll << cnt) - 1;ans += (num & mask) + 1;}}return ans;};//二分long long left = 0,right = k << x;//找靠近右边最大的num,因此要固定右边枚举左边。while(left < right){long long mid = (left + right + 1) / 2;if(check(mid) > k)right = mid - 1;elseleft = mid;}//必然会有答案。return left;}
};
  • 补充一点:这里的right 是 最多 num 能取到的数,设为上界,具体分析跟位运算的分析雷同,看奇数位且只看最低位,即 (num / 2x-1 - 1) / 2 == k,解出上界,取一个大于 num 的即可。当然如果不想这样写,也可以直接枚举最大值作为上界。

3.3008. 找出数组中的美丽下标 II

  • 题目链接:找出数组中的美丽下标 II

  • 题目大思路:KMP + 【二分】/ 【双指针】

  • 前置知识 ——【数据结构与算法】KMP算法
  • KMP模版
vector<int> kmp(string& text,string& pattern)
{//求next数组int tsz = text.size(),psz = pattern.size();vector<int> next(psz);int index = 0;for(int i = 1; i < psz; i++){char ch = pattern[i];while(index && ch != pattern[index]){//进行回退找最长匹配串与之匹配index = next[index-1];}if(ch == pattern[index])index++;next[i] = index;}vector<int> ans;//求子串的起始位置。index = 0;for(int i = 0; i < tsz; i++){char ch = text[i];while(index && ch != pattern[index]){index = next[index-1];}if(ch == pattern[index])index++;if(index == psz){//说明找到子串了,记录下标并进行回退ans.push_back(i + 1 - psz);index = next[index - 1];}}return ans;
};
  1. 双指针,因为要找 |j - i| <= k 的,所以我们固定 i找符合满足的 j 即可, 可以让j追i,当 j < i - k, 就让k++, 追上 i 或者 超过i 就停下。
  • 实现代码:
class Solution {
public:vector<int> beautifulIndices(string s, string a, string b, int k) {vector<int> res;vector<int> pos_a = kmp(s,a);vector<int> pos_b = kmp(s,b);int asz = pos_a.size(),bsz = pos_b.size();int j = 0;for(int i = 0; i < asz; i++){//让 j 追 i 且满足pos_b[j] < pos_a[i] - k, 就去追while(j < bsz && pos_b[j] + k < pos_a[i])j++;// 追上了,且满足情况if(j < bsz && abs(pos_a[i] - pos_b[j]) <= k)res.push_back(pos_a[i]);}return res;}
};
  1. 二分,也是固定 i , 二分找 j,因为pos_b存的是下标是递增的,因此可以二分找,我们可以找 大于等于 pos_a[ i ] 的第一个pos_b[ j ]pos_b[j - 1]可能是靠近pos_a[i]的其左边最近的那一个,对这两种情况进行讨论即可。
  • 实现代码:
   vector<int> beautifulIndices(string s, string a, string b, int k) {vector<int> res;vector<int> pos_a = kmp(s,a);vector<int> pos_b = kmp(s,b);int asz = pos_a.size(),bsz = pos_b.size();for(int i = 0; i < asz; i++){//二分找左边那个j  >= i 的最靠近的元素int left = 0,right = bsz - 1;while(left <  right){int mid = (left + right - 1) / 2;if(pos_b[mid] < pos_a[i])left = mid + 1;elseright = mid;}if(right >= 0 && pos_b[right] >= pos_a[i]){left = right - 1;}else{left = bsz == 0 ? -1 : right;right = bsz;}if( right < bsz && pos_b[right] - pos_a[i] <= k || left >= 0 && pos_a[i] - pos_b[left] <= k){res.push_back(pos_a[i]);} }return res;}
};
  • 这里的二分,要对结果判断一下是否有效,且这里 left是 pos_b 左边最靠近 pos_a[i ] 的,right 是 pos_b右边最靠近 pos_a[i]的。
  • 推荐双指针的写法。

总结

  1. 第一道题的一种遍历写法值得品味一番。
  2. 第二道题的数位dp + 位运算 需要认真思考。
  3. 第三道题的KMP算法 的线性复杂度值得探索。
  • 彩蛋:如果存在两个题目相同,可以先把简单的AC掉,然后用难的去简单的上测试,出错是不会罚时的哦!

尾序

我是舜华,期待与你的下一次相遇!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“货到人”拣选系统模式|智能四向穿梭车系统如何节约仓储空间优化企业供应链?

随着仓储物流和电商行业的快速发展&#xff0c;自动化立库设备的技术不断完善。“货到人”拣选技术越来越受到行业的重视&#xff0c;且已逐渐成为供需双方关注的焦点。“货到人”拣选系统主要由储存系统&#xff0c;补货系统&#xff0c;输送系统&#xff0c;拣选系统和包装系…

嵌入式软件工程师面试题——2025校招社招通用(二十)

说明&#xff1a; 面试群&#xff0c;群号&#xff1a; 228447240面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但…

Hive条件函数详细讲解

Hive 中的条件函数允许你在查询中基于某些条件执行逻辑操作。以下是你提到的条件函数的详细讲解,包括案例和使用注意事项: IF() 功能:根据条件返回两个表达式中的一个。语法:IF(boolean_test, value_if_true, value_if_false)案例:SELECT IF(1=1, true, false); 结果为 tr…

C语言宏定义(#define定义常量​、#define定义宏​、 带有副作用的宏参数、 宏替换的规则、 宏函数的对比)

目录 一、#define的基本语法 二、什么是宏 三、#define定义常量用法 基本语法&#xff1a; 思考&#xff1a;在define定义标识符的时候&#xff0c;要不要在最后加上 ; 四、#define定义宏 五、带有副作用的宏参数​ 六、宏替换的规则​ 七、宏与函数的对比​ 一、#def…

tinyxml2

tinyxml2类对象 链接 XMLDocument xml文档(文件)对象。 作用&#xff1a; 加载xml文件&#xff0c;

前端js 数据结构:对象 object、数组Array 、Map 的创建、增删改 / 遍历数据

目录 前端js 数据结构&#xff1a;对象、数组、Map 的使用1 对象&#xff08;object&#xff09;1.1 创建对象1.1.1 对象字面量(最常用): {}1.1.2 使用 new 关键字和对象构造函数1.1.3 Object.create() 1.2 修改对象1.2.1 直接赋值&#xff1a;对象的属性名直接赋值1.2.2 点号/…

介绍 Apache Spark 的基本概念和在大数据分析中的应用

Apache Spark 是一个开源的分布式计算系统&#xff0c;它旨在处理大规模数据集并提供高性能和易用性。Spark 提供了一个统一的编程模型&#xff0c;可以在多种编程语言中使用&#xff0c;包括 Scala、Java、Python和R。Spark 的主要特点包括&#xff1a; 快速&#xff1a;Spark…

网页设计(八)HTML5基础与CSS3应用

一、当当网企业用户注册页面设计 当当网企业用户注册页面 改版后当当网企业用户注册页面 <!-- prj_8_1.html --> <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>当当网企业用户注册页面设计</title><s…

第13章 1 进程和线程

文章目录 程序和进程的概念 p173函数式创建子进程Process类常用的属性和方法1 p175Process类中常用的属性和方法2 p176继承式创建子进程 p177进程池的使用 p178并发和并行 p179进程之间数据是否共享 p180队列的基本使用 p180使用队列实现进程之间的通信 p182函数式创建线程 p18…

Docker的本地化部署:加速软件开发周期的利器

在软件开发中&#xff0c;部署是一个至关重要的环节。随着云计算的兴起&#xff0c;人们开始在云端环境中进行应用部署&#xff0c;以获得更好的灵活性和可扩展性。然而&#xff0c;一些场景中&#xff0c;本地化部署仍然是必要的&#xff0c;它提供了更高的安全性和可控性。 本…

【算法Hot100系列】接雨水

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

git报错fatal: detected dubious ownership in repository at

git报错 在git上执行 git branch fatal: detected dubious ownership in repository at ‘/home/你的用户名/cam/code’ To add an exception for this directory, call: git config --global --add safe.directory /home/你的用户名/cam/code这个一般是权限不足导致的&#…

码云星辰:未来运维的技术交响曲

&#x1f6a9;本文介绍 ​ 随着信息技术的迅猛发展&#xff0c;运维领域正经历着翻天覆地的变革。未来的运维工程师将需要拥有更广泛、更深入的技能&#xff0c;以适应日益复杂和多变的系统环境。本文将深入探讨运维未来的行业发展趋势&#xff0c;并详细分析需要掌握的关键技…

AP上线配置流程

AP工作模式 相应地&#xff0c;AR路由器的WLAN工作模式分为FAT AP和AC两种模式&#xff0c;不同的模式对应不同的使用场景。 FAT AP模式&#xff1a;AR路由器作为FAT AP&#xff0c;独立为用户提供WLAN接入服务&#xff0c;无线网络的配置在FAT AP上单独配置。FAT AP模式主要…

Angular系列教程之单向绑定与双向绑定

文章目录 介绍单向绑定双向绑定在自定义组件中实现双向绑定属性总结 介绍 在Angular开发中&#xff0c;数据的绑定是非常重要的概念。它允许我们将应用程序的数据与用户界面进行交互&#xff0c;实现数据的动态更新。在本文中&#xff0c;我们将探讨Angular中的两种数据绑定方…

❤ Uniapp使用四( 高阶使用配置和各种实现篇)

❤ Uniapp使用四( 复杂配置和各种实现篇) uniapp引入 vant 引入方式 1、下载vant源码 方式一&#xff1a;从 Vant 官网首页进入 GitHub下载对应版本的压缩包,将文件解压后备用,确保下载的压缩包里有dist 文件夹 2、创建 uniapp 项目,在根目录下新建 一个文件夹wxcomponents …

133基于matlab的智能微电网粒子群优化算法

基于matlab的智能微电网粒子群优化算法&#xff0c;输出微型燃气轮机、电网输入微网运行计划、储能运行计算。程序已调通&#xff0c;可直接运行。 133智能微电网粒子群优化算法 (xiaohongshu.com)

Edge-TTS(文字转语音工具)Html版本

无需安装任何环境,运行html文件就能完成语音合成 软件说明 Edge-TTS绿色版(语音模型训练)是一款提取自微软Edge的文字转语音软件!众所周知,微软的Edge语音非常自然又顺畅,很受大家欢迎。该软件采用了最新的端到端学习技术,具有高度的自适应能力,能够适应各种语音场景和…

Excel 动态可视化图表分享

AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 数据库Mysql 8.0 54集 数据库Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战&#xff0c; ETL Informatica 数据仓库案例实战 Excel 2021实操 100集&#xff0c; Excel 2021函数大全 80集 Exc…

2024.1.15 Spark 阶段原理,八股,面试题

目录 1. 简述什么是Spark? 2. 简述Spark的四大特点 3. 简述Spark比Mapreduce执行效率高的原因 4. 简述Spark on Yarn的两种部署模式的区别和特点 5. Spark底层工作原理是怎样的 6. RDD算子分成了哪几类,各自的特点是什么? 7. RDD的五大特性和五大特点 8. RDD中的重分…