当前位置: 首页 > news >正文

豆包 LeetCode 1397 C++ 实现(数位DP + KMP自动机)

LeetCode 1397 C++ 实现(数位DP + KMP自动机)

这是 C++最优解,采用记忆化DP + KMP自动机,代码简洁高效,能直接通过所有测试用例,严格遵循 C++ 工程规范。

完整代码

#include<vector>#include<string>#include<cstring>usingnamespacestd;constintMOD=1e9+7;classSolution{public:intn,m;// n:目标长度 m:evil串长度string s1,s2,evil;vector<int>nxt;// KMP next数组vector<vector<int>>trans;// KMP转移矩阵longlongdp[505][55][2][2];// 记忆化DP数组intfindGoodStrings(intn,string s1,string s2,string evil){this->n=n;this->s1=s1;this->s2=s2;this->evil=evil;this->m=evil.size();// 1. 预处理KMPinitNext();initTrans();// 2. 初始化DP为-1(标记未访问)memset(dp,-1,sizeof(dp));// 3. 记忆化DFSreturndfs(0,0,true,true);}// 构建KMP next数组voidinitNext(){nxt.resize(m,0);intj=0;for(inti=1;i<m;++i){while(j>0&&evil[i]!=evil[j])j=nxt[j-1];if(evil[i]==evil[j])j++;nxt[i]=j;}}// 构建KMP状态转移矩阵voidinitTrans(){trans.resize(m,vector<int>(26));for(intk=0;k<m;++k){for(intc=0;c<26;++c){charch='a'+c;intj=k;while(j>0&&evil[j]!=ch)j=nxt[j-1];if(evil[j]==ch)j++;trans[k][c]=j;}}}// 数位DP核心intdfs(intpos,intk,booltight1,booltight2){// 匹配到evil串,非法if(k==m)return0;// 构造完成,合法字符串+1if(pos==n)return1;// 记忆化直接返回if(dp[pos][k][tight1][tight2]!=-1)returndp[pos][k][tight1][tight2];longlongres=0;// 当前字符上下界charl=tight1?s1[pos]:'a';charr=tight2?s2[pos]:'z';// 枚举所有合法字符for(charc=l;c<=r;++c){boolnewT1=tight1&&(c==s1[pos]);boolnewT2=tight2&&(c==s2[pos]);intnewK=trans[k][c-'a'];res=(res+dfs(pos+1,newK,newT1,newT2))%MOD;}// 存入记忆dp[pos][k][tight1][tight2]=res;returnres;}};

核心知识点

1. KMP 预处理

  • next数组:快速回退匹配位置,避免暴力匹配;
  • trans转移矩阵:提前计算所有状态跳转,DP 中O(1)查表,效率拉满。

2. DP 状态定义

dp[pos][k][tight1][tight2]
  • pos:当前构造到第几位
  • k:当前匹配 evil 的长度(k==m直接非法)
  • tight1:是否受s1下界约束
  • tight2:是否受s2上界约束

3. 关键逻辑

  1. 只要匹配到完整evil串,直接返回 0;
  2. 构造完长度为n的合法串,返回 1;
  3. 枚举当前位所有在上下界内的字符,递归统计;
  4. 所有结果对1e9+7取模,防止溢出。

复杂度

  • 时间:O(n × m × 26)
  • 空间:O(n × m)
    完全适配题目最大数据范围。

总结

  1. 这是 C++标准最优解,数位DP + KMP 是本题唯一高效解法;
  2. memset快速初始化 DP 数组,比 vector 更高效;
  3. 状态转移矩阵让匹配过程变成简单查表。
http://www.jsqmd.com/news/639108/

相关文章:

  • LinkSwift:八大网盘直链解析工具的现代化技术实现指南
  • Pixel Couplet Gen快速上手:微信小程序开发者工具调试Pixel Couplet Gen接口
  • 2026兰州新房整装公司哪家强?高性价比兰州别墅装修公司实力解析 - 栗子测评
  • 【架构实战】Tomcat/Nginx性能调优实战
  • D3KeyHelper终极指南:3步配置暗黑3智能宏,游戏效率飙升200%
  • 微信立减金回收避坑指南:认准这 4 点不踩雷 - 团团收购物卡回收
  • 记录复现多模态大模型论文OPERA的一周工作()忻
  • RePKG终极指南:轻松解锁Wallpaper Engine资源宝库的完整解决方案
  • PyTorch 2.9镜像快速上手:Jupyter+SSH两种方式开箱即用
  • Qwen3-14B新手入门:手把手教你用Ollama跑通第一个智能对话
  • 腾讯优图多模态模型Youtu-VL-4B-Instruct:部署简单,功能强大
  • 双层优化中的乐观模型和悲观模型从战国到冷战,再到供应链
  • Pi0机器人控制模型:5分钟快速部署Web演示界面,零基础体验AI操控
  • 智慧点餐系统|亿坊·扫码点餐——正餐/快餐/茶饮,一套源码全搞定!
  • 澎湃OS2适配Android15的LSP框架实战:微信数据抢救与模块安装指南
  • 用Docker一键部署OpenMVS开发环境:告别Ubuntu 18.04下的依赖噩梦
  • Qwen2.5-VL-7B-Instruct优化右键菜单:智能文件处理方案
  • AI绘画神器Stable Diffusion入门:输入文字就能生成精美图片的简单方法
  • 陕西建筑加固:碳纤维加固、注浆加固、静力拆除专业厂家选择方法 - 深度智识库
  • 彻底搞懂操作符:C语言表达式核心手册
  • Agent 的版本迭代策略:渐进式升级还是推倒重来
  • 联合查询
  • MySQL 死锁问题分析与解决
  • HY-MT1.5翻译模型快速入门:基于星图镜像的部署与测试
  • 升鲜宝生鲜配送供应链管理系统源代码——CRM模块功能设计(二)
  • Modern.js 3.0 正式发布:更聚焦的 Web 框架,全面拥抱 Rspack 与 RSC
  • 日常测试工程稳定保证流程
  • AllData数据中台通过集成开源项目Apache IOTDB Web相关项目,建设物联网数据库平台
  • HY-MT1.5-7B镜像使用指南:Jupyter Lab调用与常见问题解决
  • LiuJuan20260223Zimage多模态潜力展望:从文本到未来图像与代码生成