当前位置: 首页> 娱乐> 影视 > dp经典问题:LCS问题

dp经典问题:LCS问题

时间:2025/7/12 15:59:30来源:https://blog.csdn.net/bairui6666/article/details/139935343 浏览次数:0次

dp:LCS问题

最长公共子序列(Longest Common Subsequence, LCS)问题 是寻找两个字符串中最长的子序列,使得这个子序列在两个字符串中出现的相对顺序保持一致,但不要求连续。

力扣原题链接

1.定义

给定两个字符串 S1和S2
S 1 = a 1 a 2 a 3 . . . a n → 长度为 n 的字符串 S1=a_1a_2a_3...a_n \to 长度为n的字符串 S1=a1a2a3...an长度为n的字符串
S 2 = b 1 b 2 b 3 . . . b m → 长度为 m 的字符串 S2=b_1b_2b_3...b_m \to 长度为m的字符串 S2=b1b2b3...bm长度为m的字符串

子序列(Subsequence)

一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在 不改变字符的相对顺序 的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。

对于 S1 来说

S s u b = a i . . . a j ← i < j , S s u b ∈ S 1 S_{sub}=a_i...a_j \gets i<j, S_{sub} \in S1 Ssub=ai...aji<j,SsubS1

比如说

S 1 = a b c d f g h S_1=abcdfgh S1=abcdfgh

S 2 = a b d f h r S_2=abdfhr S2=abdfhr

S 1 ∩ S 2 = a b d f h S_1 \cap S_2 = abdfh S1S2=abdfh

2. 动态规划解法

Step1 分析子问题

对于每个子问题都要求出到当前两个子字符串的最长公共子序列。

Step2 状态定义

dp[i][j] 表示 text1 的前 i 个字符与 text2 的前 j 个字符的最长公共子序列长度。

Step3 递推求解

  1. 初始化状态:

    • i == 0j == 0 时,dp[i][j] = 0,因为任意一个空字符串与另一个字符串的最长公共子序列长度为 0。
  2. 状态转移方程:

d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ] + 1 if text1[i] = text2[j] max ⁡ ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) if  text1[i]  ≠ text2[j] dp[i][j] = \left\{ \begin{array}{ll} dp[i-1][j-1] + 1 & \text{if } \text{text1[i] = text2[j]} \\ \max(dp[i-1][j], dp[i][j-1]) & \text{if } \text{text1[i] $\neq$ text2[j]} \end{array} \right. dp[i][j]={dp[i1][j1]+1max(dp[i1][j],dp[i][j1])if text1[i] = text2[j]if text1[i] = text2[j]

示例

在这里插入图片描述

动态规划代码实现

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {int m = text1.size();int n = text2.size();vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));for (int i = 1; i <= m; ++i) {for (int j = 1; j <= n; ++j) {if (text1[i - 1] == text2[j - 1]) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[m][n];}
};

递归代码实现
递归调用的开销会很大,力扣这个题会超时

class Solution{int longestCommonSubsequence(string text1, string text2) {return rec(text1,text2,text1.size()-1,text2.size()-1);}int rec(const&string str1,const&string str2,int m,int n){if(m==0||n==0)return 0;if(str1[m]==str[n]){return 1+rec(str1,str2,m-1,n-1);}else{return max(rec(str1,str2,m-1,n),rec(str1,str2,m,n-1));}}
}
关键字:dp经典问题:LCS问题

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: