动态规划——最长公共子串,没有比这更通俗易懂的了

article/2025/9/20 14:43:43

前言

动态规划是大厂的热门考点,其中最长公共子串与最长公共子序列这两道题出现得尤其频繁,这两道题其实有挺多变种,很适合考察侯选人对动态规划的掌握情况,今天我们就先来看看如何求解最长公共子串,图文并茂,清晰易懂!

最长公共子串

题目如下:

输入: x = ["", "a", "b", "c", "a", "d", "f"] y = ["", "a", "c", "b", "a", "d"],输出: 2解释: 最长公共子串为 ad,所以结果为 2这里需要简单解释下子串与子序列的区别,子串要求这串字符串在原字符串中是连续的,而子序列可以不连续,两者的区别如下:

 

小结一下

首先看下,如果这题如果用暴力求解的话,应该算出每个字符串的所有子字符串,然后再对所有子字符串进行比较,是个排列组合问题,时间复杂度很大,不可取!所以我们看下怎么用动态规划来解。

解动态规划需要至少明确以下三个概念

  • base case
  • 状态转移方程
  • 自下而上

动态规划一言以蔽之就是利用 「base case 」和「状态转移方程」然后「自下而上」得求得最终问题的解。相对递归的自上而下求解造成的大量子问题的计算,自下而上意味着每个子问题不会被重复计算,很好地达到了「剪枝」的效果。这其中「状态转移方程」的求解无疑是重要的,如果求得了「状态转移」方程,问题其实就解决地差不多了。

回到最长公共子串本身来看,我们来看看它的「状态转移方程」和「base case」是啥。

1、状态转移方程

这题的状态转移方程该怎么定义呢,首先我们求的是两个字符串的公共子串,所以应该意识到这个 dp 方程是个二维数组 dp[i][j],代表的 x 的前 i 个字符串与 y 的 前 j 个字符串的最长公共子串,

那么状态状态方程该怎么得出来呢,一般对于字符串类的动态规划来说,我们可以利用「状态转移表」法来帮助我们得出状态转移方程

 

观察出规律了吗,对于 dp[i][j] 来说,它的值有两种可能,取决于字符 x[i] 和 y[j] 这两个字符是否相等

如果两个字符相等,则 dp[i][j] = dp[i-1][j-1] + 1(注意图中的箭头), 怎么理解,1 代表 x 的第 i 个字符与 y 的第 j 个字符相等,根据 dp[i][j] 的定义,那么它自然等于 x 的前 i-1 个字符串与 y 的 前 j-1 个字符串的最长公共子串 + 1,如下图示

 

如果 x 的第 i 个字符与 y 的第 j 个字符不相等,那么显然 dp[i][j] = 0,因为 dp[i][j] 定义为最长公共子串,所以只要有一个字符不相等,就说明不满足最长公共子串这个定义,自然 dp[i][j] 为 0 了。

根据以上条件可知状态转移方程为:

 

2、base case

显然图中黄色格子所示为 base case

即可用如下公式表示

这也比较好理解,dp[0][i] 或 dp[j][0] 即空字符串与任意字符串的最大公共子串显然为0。

 

3、求解

 ​​​​​​

 这里需要注意下标,因为我们的i、j是从1开始遍历,而我们的字符串字符下标是从0开始的,所以应该是i-1和j-1, 这里 i j代表的是字符串的长度,所以是从1开始 因为0的是初始值都为0

 代码实现:

这里给出C++代码(C语言代码见上图),实现了输出最长的公共子串

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<math.h>
using namespace std;
int main(){string s1,s2;cin>>s1>>s2;if(s1.size() > s2.size()) //以短的作为s1swap(s1,s2);int len1 = s1.size(), len2 = s2.size();int start = 0, mx = 0; //记录结果vector<vector<int> > dp(len1+1,vector<int>(len2+1,0));for(int i = 1;i<=len1;i++){for(int j = 1;j<=len2;j++){if(s1[i-1] == s2[j-1])dp[i][j] = dp[i-1][j-1] + 1;if(dp[i][j] > mx){mx = dp[i][j];start = i - mx;}}}cout<<s1.substr(start,mx);return 0;
}

http://chatgpt.dhexx.cn/article/8dNUdtZ2.shtml

相关文章

SQL中字符串拼接方法(MySQL,SQLServer)

1 SQLServer &#xff08;1&#xff09;用号实现字符串拼接 select 123456; &#xff08;2&#xff09;用concat()内置函数实现字符串拼接 注&#xff1a;SQLServer 2012及更高版本才支持conconcat()函数。 select concat(123,456);//两个字符串拼接 2 MySQL &#xff0…

mysql 使用group by分组后对某个字段值拼接成字符串方法,一般人都不知道!

只需要使用GROUP_CONCAT函数可以在使用groupby分组后&#xff0c;将某个字段的值进行拼接合并 使用示例&#xff1a; 数据表&#xff1a;testTb 使用 GROUP_CONCAT函数来实现&#xff0c;我们的sql可以这样写 Select albumId,GROUP_CONCAT(name) from testTb group by albumI…

MySql查询结果拼接成字符串

背景&#xff1a;做SQL查询时会经常需要&#xff0c;把查询的结果拼接成一个字符串。 解决方法&#xff1a; 通过 group_concat 函数 1.正常查询 如下: select id result from ctp_enum_item limit 100; 2.拼接结果 如下 select group_concat("",id,"") r…

MySQL 字符串拼接

在Mysql 数据库中存在两种字符串连接操作.具体操作如下 一. 语法: 1. CONCAT(string1,string2,…) 说明 : string1,string2代表字符串,concat函数在连接字符串的时候&#xff0c;只要其中一个是NULL,那么将返回NULL 例1: 例2: 2. CONCAT_WS(separator,str1,str2,...) 说明 : …

MySQL字符串合并

MySQL有几种合并字符串的方式&#xff0c;下面来介绍一下 CONCAT函数 concat(str1, str2,...) 返回结果为连接参数产生的字符串&#xff0c;如果有任何一个参数为null&#xff0c;则返回值为null。 mysql> select concat(www,MySQL,substringIndex,com) ----------------…

mysql concat字符串拼接函数使用

目录 1、concat 2、concat_ws 3、group_concat 1、concat select CONCAT(h,e,llo) from dual; 2、concat_ws 指定分隔符进行字符串的拼接 select CONCAT_WS(_,h,e,llo) from dual;3、group_concat 用法&#xff1a; group_concat( [distinct] {要连接的字段}[order by …

MySQL如何分组拼接字符串?

上一篇文章 跨表更新&#xff0c;看到自己写的SQL像个憨憨 写了关于跨表个更新的内容。一年过的很快&#xff0c;文中后来的两位员工 馮大 和 馮二 也要面对无情的 KPI 考核了&#xff0c;他们工作干的很不错&#xff0c;performance 分别是 4 和 5 新需求来了&#xff0c;静悄…

MySQL字符串拼接函数

MySQL字符串拼接函数有以下三个&#xff1a; CONCATCONCAT_WSGROUP_CONCAT 1.CONCAT 说明 对指定字符进行拼接 语法 CONCAT(str1,str2,...) 语法说明&#xff1a; CONCAT(字符1,字符2,...) 实例 SELECT CONCAT(this ,is ,a ,demo) AS result FROM DUAL2.CONCAT_WS 说明 …

mysql 实现字符串的拼接

在Mysql 数据库中存在两种字符串连接操作.具体操作如下 一. 语法: 1. CONCAT(string1,string2,…) 说明 : string1,string2代表字符串,concat函数在连接字符串的时候&#xff0c;只要其中一个是NULL,那么将返回NULL 例1: 例2: 2. CONCAT_WS(separator,str1,str2,...) 说明 :…

MySQL 字符串拼接 - 多种字符串拼接实战案例

本文首发&#xff1a;MySQL 字符串拼接 - 多种字符串拼接实战案例 - 卡拉云 MySQL 字符串拼接可以使多个字段的值组成一个集合&#xff0c;不仅可以拼接字符串与字符串、空格、特殊符号甚至可以拼接中文文本&#xff0c;方便我们在不同场景下应用。 本教详细讲解 CONCAT() 和…

MySQL字符串拼接的两种方式

第一种&#xff1a; MySQL自带语法Concat(string1,string2,string3...)&#xff0c;此处是直接把string1和string2等等的字符串拼接起来&#xff08;无缝拼接哦&#xff09; 说明&#xff1a;此方法在拼接的时候如果有一个值为NULL&#xff0c;则返回NULL select concat(&qu…

MySQL字符串拼接(函数)

最近帮助处理数据,需要批量更新数据,遂上网查了查方法,在此记录一下。我的原始数据如下: 一.CONCAT()函数 说明 : CONCAT(string1,string2,string3...)&#xff0c;此处是直接把string1、string2和string3等等的字符串无缝拼接起来&#xff0c;返回结果为连接参数产生的字符…

MYSql-字符串拼接

一、MySQL自带字符串拼接函数 CONCAT 字符串拼接CONCAT_WS 指定字符串分割拼接字符串拼接 ① 语法&#xff1a;CONCAT(str1,str2…) 解释&#xff1a;concat 拼接 str1和str2字符串, 省略号....代表可以多个字符串拼接 示例&#xff1a; SELECT CONCAT("hello&quo…

MySQL字符串拼接concat()、分组拼接字符串group_concat()

MySQL拼接 一、经典拼接concat(x,x,....)二、分隔符拼接CONCAT_WS(separator,str1,str2,...)三、分组拼接GROUP_CONCAT(expr) 一、经典拼接concat(x,x,....) 用法案例&#xff1a; SELECTconcat( 字符串, 拼接, &#xff0c;啥都可以, 嘿嘿 ) AS concats FROM DUAL注意&…

SQL 拼接字符串

不同的数据库&#xff0c;相应的字符串拼接方式不同&#xff0c;下面进行详细讲解。 一、MySQL字符串拼接 1、CONCAT函数 语法格式&#xff1a;CONCAT(char c1, char c2, …, char cn) &#xff0c;其中char代表字符串&#xff0c;定长与不定长均可以 连接两个字符串 sele…

Mysql之字符串拼接

mysql字符串拼接 两种方式&#xff0c;第一种&#xff0c;使用 “” 进行拼接&#xff08;错误的方法&#xff09;&#xff0c; 第二种使用Mysql函数CONCAT()等函数。 使用 “” 使用“”进行对数据是加减。不能进行拼接 拼接用法&#xff1a; 数据表&#xff1a; 错误写法&am…

mysql中的实现字段或字符串拼接的三种方式

一、CONCAT函数 concat函数是将多个字段或字符串拼接为一个字符串&#xff1b;但是字符串之间没有任何分隔。 concat函数官方介绍 -- CONCAT函数的语法如下&#xff1a; CONCAT(str1,str2,...) 1.1、拼接非空字段或字符串 SELECT CONCAT(字段1,字段2,字段3,...) from 表名;-- 拼…

mysql 字符串拼接的几种方式

总是记不住字符串拼接&#xff0c;每次都要百度去搜索&#xff0c;所以在这里记录一下&#xff0c;好方便后续的查找&#xff0c;如有错误和问题可以提出&#xff0c;谢谢。 字符串拼接分为几种方式&#xff0c;在这里会一一举例写出&#xff1a; 第一种&#xff1a; mysql自…

Geth搭建私链(最新)

Geth搭建私链 puppeth 是 Geth 中一个非常有用的命令&#xff0c;它允许您使用一个交互式的命令行界面来创建、配置和管理您的私有链。但是在最新版本的Geth中已经删除了用于以动开发的库和puppeth工具&#xff0c;这也就给我们搭建私链增加了负担。 前提条件 1、Geth正确安…

Geth安装

结合了网上各种文章&#xff0c;经过十多个小时的失败&#xff0c;期间还把虚拟机搞得开机不了&#xff0c;但终于成功的安装了geth。下面我会展示我遇到的问题和解决方案 目录 1.系统环境 2.安装基础工具 3.安装cmake 4.安装Golang 5.防火墙及网络时间同步 6.进入geth …