动态规划 DP (六) 字符串编辑

news2024/9/22 17:36:09

1.字符串编辑

字符串编辑问题是一类常见的问题,通常涉及对字符串进行插入、删除、替换等操作,以达到某种特定的目标。

常见的字符串编辑问题包括:

  • 编辑距离(Edit Distance):给定两个字符串,通过插入、删除和替换操作,计算将一个字符串转换为另一个字符串所需的最小操作次数。编辑距离可以用于拼写纠错、DNA序列比对等领域。
  • 最长公共子序列(Longest Common Subsequence):给定两个字符串,找到它们的最长公共子序列,即在两个字符串中都存在的最长的子序列。最长公共子序列问题可以用于比较文本相似性、基因序列比对等领域。
  • 最长回文子串(Longest Palindromic Substring):给定一个字符串,找到其中最长的回文子串,即正向和反向读都相同的最长子串。最长回文子串问题可以用于文本处理、字符串匹配等领域。
  • 字符串压缩(String Compression):给定一个字符串,将连续出现的字符压缩成字符和出现次数的形式。例如,字符串"aaabbbccc"可以压缩成"a3b3c3"。字符串压缩问题可以用于数据压缩、编码等领域。

2.例题

1)

力扣icon-default.png?t=N658https://leetcode.cn/problems/edit-distance/用dp[i][j[来表示word1的前i个字符要和word2的前j个字符完全匹配,所需要的操作次数。

当i=0时,表示word1为空,word2的前j个字符要与word1完全匹配,需要删除j个字符。

当j=0时,也是类似的情况。

接下来考虑更普遍的情况,如何计算dp[i][j]。

如果word1[i]==word2[j],这表明两个新字符相等,dp[i][j]=dp[i][j]

如果word1[i]!=word2[j],这表明两个新字符不相等,要使它们匹配,有三种方法:

  • 修改word1或word2中其中一个字符,dp[i][j]=dp[i-1][j-1]
  • 删除word1或word2中其中一个字符,dp[i][j]=dp[i-1][j]+1 或者 dp[i][j]=dp[i][j-1]+1
  • 在word1或word2中增加一个字符,dp[i][j]=dp[i][j-1]+1 或者 dp[i][j]=dp[i-1][j]+1

这里通俗易懂地解释一下:

word1[i]!=word2[j],可以把word1[i]改成word1[j],这样就变成了相等的情况。

也可以删除掉word1[i],这样就需要word1[0...i-1]与word2[0...j]是相等的,所以就是dp[i-1][j]加一。

也可以在word1[i]后增加一个新字符word2[j],这样最后面的两个字符就相等了,但需要word1[0...i]与word2[0...j-1]是相等的,所以就是dp[i][j-1]加一。

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();
        vector<vector<int>> dp(m+1,vector<int>(n+1,max(m,n)+1));

        for(int i=0;i<=n;i++){
            dp[0][i] = i;
        }
        for(int i=1;i<=m;i++){
            dp[i][0] = i;
        }

        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(word1[i-1]==word2[j-1]){
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    dp[i][j] = 1 + min(dp[i-1][j-1],min(dp[i][j-1], dp[i-1][j]));
                }
            }
        }
        return dp[m][n];
    }
};

2)

力扣icon-default.png?t=N658https://leetcode.cn/problems/2-keys-keyboard/n的最少操作次数,却决于它的因子的最少操作次数。

如果n可以整除j,那么n的最少操作次数是j的最少操作次数,加上复制的一次操作和粘贴的n/j-1次操作。

也就是:dp[n] = min(dp[j]+n/j, dp[n/j]+j)

因为j和n/j地位一样,都是n的因子,所以取二者中的最小值

class Solution {
public:
    int minSteps(int n) {
        vector<int> dp(n+1,INT_MAX);
        dp[0] = 0;
        dp[1] = 0;
        for(int i=2;i<=n;i++){
            for(int j=1;j*j<=i;j++){
                if(i%j==0){
                    dp[i] = min(dp[i], dp[j]+i/j);
                    dp[i] = min(dp[i], dp[i/j]+j);
                   
                }
               
            }
        }
        return dp[n];
    }
};
   

3)

力扣icon-default.png?t=N658https://leetcode.cn/problems/regular-expression-matching/这道题真的好无语,首先这题目出的就有歧义:

  • '*' 匹配零个或多个前面的那一个元素

看到这句话,我想当然地觉得是*可以为0到多个前一个元素。

看完题解才知道,*意味着前一个元素也可以为空,*不是独立存在的,c*才是一个整体,这个整体可以为空。

基于这个假设,我设想的很复杂的c****,也是不合法的输入。

搞清楚这一点后,就清晰起来了,s和p匹配无非三种情况:

  • p是普通字母
  • p是.
  • p是*

dp[i][j]表示s[0...i-1]与p[0...j-1]的匹配情况

在前两种情况下都是正常判断是否匹配,'.'与所有字母匹配,所以:

dp[i][j] = dp[i-1][j-1]  如果s[i-1]与p[j-1]匹配成功 否则为false。

接下来考虑第三种情况,p为*

可以有两种处理方式,一是直接不匹配,把c*当作空,所以:

dp[i][j] = dp[i][j-2] 

二是s[i-1]与p[j-2]匹配成功:

dp[i][j] = dp[i-1][j]  这表示p[j-1]可以与s前面的元素匹配

代码:

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.size(), n = p.size();

        auto isMatch = [&](int i, int j){
            if(i==0) return false;
            if(p[j-1]=='.') return true;
            return s[i-1]==p[j-1];

        };

        vector<vector<bool>> dp(m+1,vector<bool>(n+1,false));
        dp[0][0] = true;

        for(int i=0;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(p[j-1]!='*'){
                    if(isMatch(i,j)){
                        dp[i][j] = dp[i-1][j-1];
                    }
                }else{
                    dp[i][j] = dp[i][j-2];
                    if(isMatch(i,j-1)){
                         dp[i][j] = dp[i][j] | dp[i-1][j];
                    }
                }
            }
        }


        return dp[m][n];
    }

   
};

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

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

相关文章

最新抖音娱乐测评小程序源码 Thinkphp后端 抖音引流小程序

最新抖音娱乐测评小程序源码 thinkphp后端 抖音引流小程序 附搭建教程 测试环境 NginxPHP7.0MySQL5.6 网站运行目录设置为 /web 数据库配置文件 \source\application\database.php 后台登录地址 http://你的域名/index.php?s/admin/passport/login

python环境

卸载旧环境 wini 打开应用卸载 删除python解释器和pycharm 删除配置文件夹JetBrains C:\Users\CJC\AppData\Roaming\JetBrains 安装 安装python解释器 安装pycharm 查看或设置该项目的解释器和安装包 快捷键 全局搜索 双击shift 当前文件中搜索 ctrl f 查看函数…

MySQL数据库对象与数据备份和还原详解

目录 一、视图 1. 什么是视图 2. 视图与数据表的区别 3. 视图的优点 4. 创建视图 二、索引 1. 什么是索引 2. 为什么要使用索引 3. 索引优缺点 4. 何时不使用索引 5. 索引何时失效 6. 索引分类 6.1 普通索引 6.2 唯一索引 6.3 主键索引 6.4 组合索引 三、数据的…

RabbitMQ系列(25)--RabbitMQ搭建镜像队列

前言&#xff1a;如果RabbitMQ集群中只有一个Broker节点&#xff0c;那么该节点的失效将导致整体服务的临时性不可用&#xff0c;并且也可能会导致消息的丢失&#xff0c;虽然可以将所有消息都设置为持久化,并且对应队列的durable属性也设置为true&#xff0c;这样可以保证消息…

mysql 常用命令综合简单运用

目录 第一大题创建数据库创建用户表及约束字段修改位置修改字段数据类型修改字段名字添加字段修改表名字删除字段修改表的存储引擎 第二大题创建表及外键和其他约束删除外键约束和查找外键名 第三大题创建数据库创建用户同时授权一些功能修改用户的密码更新权限列表查看用户的权…

pytorch线性模型 学习前要学习的基础知识

跟着刘二大人学pytorch&#xff0c;补全一下我的基础缺失 1.numpy基础 import numpy as np from PIL import Image anp.array([1,2,3]) #生成一维数组 print(a) bnp.arange(1,4)#创建等差数组&#xff0c;默认等差是1&#xff0c;数组为1&#xff0c;2&#xff0c;3&#xff0…

spring 详解三 IOC(spring实例化及后处理器)

Spring实例化基本流程 Spring在容器初始化的时候&#xff0c;读取XMl配置&#xff0c;将其封装成BeanDefinition(Bean定义)对象&#xff0c;描述所有bean的信息 BeanDefinition会注册存储到beanDefinitionMap集合中 Spring框架遍历beanDefinitionMap&#xff0c;使用反射创建Be…

pycharm如何给一串中文快捷加引号(方法二)

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注 回复“书籍”即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 商人重利轻别离&#xff0c;前月浮梁买茶去。 大家好&#xff0c;我是皮皮。 一、前言 前几天在Python白银群【此类生物】问了一个Pycharm基础的问题&a…

SpringBoot配置动态定时任务

1.配置ScheduledTask 主要是实现SchedulingConfigurer&#xff0c;动态传入cron。 package com.hzl.boot.config;import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Propert…

使用promise函数封装post请求,封装aes加解密方法,并进行请求头aes加密,封装sm2国密加解密,进行请求体数据加密,响应数据解密。

export default {async post(url, params { header:{}, data:{} }, showLoading true){if(showLoading){uni.showLoading({title:"加载中",mask:true})}let options{header:{...params.header},url:globalParams.basepathurl.url,data:{...params.data}}//渠道 ae…

Devops系列五(CI篇之pipeline libraray)jenkins将gitlab helm yaml和argocd 串联,自动部署到K8S

一、说在前面的话 本文是CI篇的上文&#xff0c;因为上一篇已经作了总体设计&#xff0c;就不再赘述&#xff0c;有需要的请看前文。 我们将演示&#xff0c;使用CI工具–jenkins&#xff0c;怎么和CD工具–argocd串联&#xff0c;重点是在Jenkins该怎么做。准备工作和argocd等…

C++常用库函数 5.输入和输出函数

函数名&#xff1a;fclose 函数原型&#xff1a;int fclose(FILE *stream)&#xff1b; 参数&#xff1a;streamFILE 结构的指针。 所需头文件&#xff1a;<cstdio> 返回值&#xff1a;如果该流成功关闭&#xff0c;fclose 返回0。如果出错&#xff0c;则返回 EOF。 功…

AI在金融领域的应用

AI金融领域 信贷业务 个人信贷单笔数额小、数量大&#xff0c;需要大量的人力和时间投入&#xff0c;信贷审核的数据也呈现出分散化、碎片化的特点。同时传统金融机构和互联网金融公司的风控环节中&#xff0c;普遍存在信息不对称、成本高、时效性差、效率低等问题&#xff0c…

动态规划之343 整数拆分(第6道)

题目&#xff1a; 给定一个正整数 n &#xff0c;将其拆分为 k 个 正整数 的和&#xff08; k > 2 &#xff09;&#xff0c;并使这些整数的乘积最大化。 返回 你可以获得的最大乘积 。 示例&#xff1a; 解法&#xff1a; 其实可以从1开始遍历 j &#xff0c;然后有两种…

Mysql之视图,索引,备份与恢复

目录 一&#xff0c;视图 1.视图是什么&#xff1f; 2.视图的重要性&#xff1f; 3.那些地方使用视图&#xff1f; 4.基本语法 二&#xff0c;索引 1.索引是什么&#xff1f; 2.索引的重要性&#xff1f; 3.索引的种类&#xff1a; 4.那些地方使用索引&#xff1f; 5.…

Gateway服务集成Nacos2021.0.4错误解决

问题 gateway服务集成nacos&#xff0c;启动后报错&#xff1a; Caused by: com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information:; 版本&#xff1a; jdk:1.8 spring-b…

10_Linux中断

目录 Linux中断API函数 中断号 上半部与下半部 软中断 tasklet 工作队列 设备树中断信息节点 获取中断号 修改设备树文件 按键中断驱动程序编写 编写测试APP Linux中断API函数 先来回顾一下裸机实验里面中断的处理方法: 1.使能中断,初始化相应的寄存器。 2.注册中…

windows配置启动若依前后端项目

一、后端 1、环境准备 JDK8、Redis、Mysql、Maven【并配置镜像源】 以上工具全部使用msi/exe安装&#xff0c;并勾选添加到环境变量&#xff0c;如果没有添加到环境变量可以参考其他博主关于每种怎么配置的情况 mysql新增一个目录名为ry-vue的空数据库 2、前往若依官网下载…

MAC M1上docker rocketmq简单环境搭建和代码

工作了这么多年&#xff0c;rocketmq还没有用过&#xff0c;由于现在的工作中涉及到了&#xff0c;周六吃完午饭就开始搞&#xff0c;结果到现在3点钟才把环境弄好&#xff0c;测试代码搞起。 整个流程分成两步 安装简单的rocket环境起springboot项目测试 参考文章&#xff…

C++STL库常用库函数总结

文章目录 1.vector, 变长数组&#xff0c;倍增的思想 size() 返回元素个数empty() 返回是否为空clear() 清空front()/back() 访问第一个元素/最后一个元素push_back()/pop_back() 插入/弹出最后一个元素begin()/end() 开始元素迭代器/结尾元素迭代器[]支持…