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

【LeetCode】动态规划——72.编辑距离、10.正则表达式匹配

LeetCode题目链接
https://leetcode.cn/problems/edit-distance/description/
https://leetcode.cn/problems/regular-expression-matching/description/

题解
72.编辑距离
本题要定义为长度为i、长度为j的字符串的最少编辑次数,每次判断字符的下标为i-1、j-1。dp[i][j]的状态由dp[i-1][j]、dp[i][j-1]、dp[i-1][j-1]共同决定,从dp[i-1][j]到dp[i][j]表示word1加上下标为i-1的字符后,与word2的距离差距,可以得知dp[i][j]=dp[i-1][j]+1;同理可得dp[i][j]=dp[i][j-1]+1,即word1加上第j-1个字符后所需的操作的个数多了个1,可以理解为删除;同理,此处需判断两个字符串的当前下标为i-1的字符和下标为j-1的字符是否相等,如果相等,就不需要增加操作个数,直接等于dp[i-1][j-1]即可,如果不相等,需要替换一次(不是删除两次,要求最小操作个数),则就等于dp[i-1][j-1]+1。由此可以的值最终dp[i][j]由上三者取最小值即可。同时对于初始化,由于第0行和第0列分别代表空字符串与word1、word1的挨个字符所需的操作次数,因此需要初始化为对应的递增值,简单点可以直接初始化为下标i、下标j的值即可。

10.正则表达式匹配
思路详见题解,c++版代码详见评论区。
需要注意的是判断*这个字符时,它与前面一个字符的组合可以被干掉,也就是可以重复0次(根据题意),因此可以往前跳两位字符再继续判断。

代码

#include <iostream>
#include <string>
#include <vector>
using namespace std;class Solution {
public:int minDistance(string word1, string word2) {vector<vector<int>> dp(word2.size() + 1, vector<int>(word1.size() + 1, 0));for (int i = 0;i <= word2.size();i++) {dp[i][0] = i;}for (int j = 0;j <= word1.size();j++) {dp[0][j] = j;}for (int i = 1;i <= word2.size();i++) {for (int j = 1;j <= word1.size();j++) {if (word2[i - 1] == word1[j - 1]) {dp[i][j] = min(dp[i - 1][j] + 1, min(dp[i][j - 1] + 1, dp[i - 1][j - 1]));}else {dp[i][j] = min(dp[i - 1][j] + 1, min(dp[i][j - 1] + 1, dp[i - 1][j - 1] + 1));}}}printf("dp[i][j]\n");for (int i = 0;i <= word2.size();i++) {for (int j = 0;j <= word1.size();j++) {printf("%d ", dp[i][j]);}printf("\n");}return dp[word2.size()][word1.size()];}
};int main() {Solution s;string word1 = "intention";string word2 = "execution";printf("%d", s.minDistance(word1, word2));return 0;
}
//10.正则表达式匹配
#include <iostream>
#include <vector>
#include <string>
using namespace std;class Solution {
public:bool isMatch(string s, string p) {if (p.empty() && !s.empty()) return false;//if (s.empty() && !p.empty() && p[j - 1] != '*') return false;vector<vector<bool>> dp(s.size() + 1, vector<bool>(p.size() + 1, false));dp[0][0] = true; //两个空字符串for (int j = 1;j <= p.size();j++) {  //s为空,但p因为* 可以干掉一个字符(即题意中的可以重复零次)if (p[j] == '*')dp[0][j + 1] = dp[0][j - 1];}for (int i = 1;i <= s.size();i++) {for (int j = 1;j <= p.size();j++) {if (s[i - 1] == p[j - 1] || p[j - 1] == '.') {dp[i][j] = dp[i - 1][j - 1];}else {if (p[j - 1] == '*') {if (s[i - 1] == p[j - 2] || p[j - 2] == '.') {dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j];   //重复0次、重复1次、重复2次以上}else {dp[i][j] = dp[i][j - 2];  //不匹配,*干掉一个字符}}}}}return dp[s.size()][p.size()];}
};int main() {Solution s;string str1 = "ab";string str2 = ".*";printf("%d", s.isMatch(str1, str2));return 0;
}
http://www.dtcms.com/a/357412.html

相关文章:

  • Springboot高校迎新系统2cbcd(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 独角数卡对接蓝鲸支付平台实现个人发卡
  • CS144 lab3 tcp_sender
  • Day16(前端:JavaScript基础阶段)
  • Pycharm打包PaddleOCR过程及问题解决方法
  • Go语言-->if判断中的;
  • SOME/IP-SD协议中组播IP地址和端口号应从何处获取、由谁设置?
  • 嵌入式Linux字符设备驱动开发
  • LFI-labs靶场通关教程
  • 串口通信1.0(串行并行)
  • 解决多种类潮湿敏感元器件的多温度、多时长的排潮烘干
  • 订餐后台项目-day02数据库模型定义笔记
  • DAY16-新世纪DL(DeepLearning/深度学习)战士:Q(机器学习策略)1
  • Go语言入门(13)-map
  • 科学融智学引领人机协同教育新范式
  • 吴恩达机器学习作业七:方差与偏差
  • 【上位机数据转换】数据结构原理及大小端
  • 《WINDOWS 环境下32位汇编语言程序设计》第8章 通用对话框
  • ssh端口转发的几种常用使用方式【本地端口转发、远程端口转发、反向端口转发、动态端口转发】
  • Jenkins 全方位指南:安装、配置、部署与实战应用(含图解)
  • Two-Twer模型做歌曲智能推荐与规则算法对比的优缺点分析
  • 对比rerank模型和embedding模型
  • 订餐后台管理系统 - day04退出登录与账号管理模块
  • C#简单组态软件开发
  • AlexNet:点燃深度学习革命的「卷积神经网络之王」
  • 50etf期权与现货套利是什么意思?
  • position属性
  • Linux学习:线程控制
  • FastAPI 入门科普:下一代高性能 Python Web 框架
  • 一般纳税人