【动态规划】最长公共子序列

  • 题目描述:给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。两个字符串的 公共子序列 是这两个字符串所共同拥有的子序列。
  • 示例 1:
    输入:text1 = "abcde", text2 = "ace" 
    输出:3  
    解释:最长公共子序列是 "ace" ,它的长度为 3 。
    
  • 分析:因为子序列并不一定是原序列中连续的序列,因此肯定要两个指针遍历分别遍历两个字符串,找到所有字符串的组合。
    1. d p [ i ] [ j ] dp[i][j] dp[i][j]表示 t e x t 1 [ : i − 1 ] text1[:i-1] text1[:i1] t e x t 2 [ : j − 1 ] text2[:j-1] text2[:j1]的公共子序列的长度,其中 i ∈ [ 0 , m ] i\in[0,m] i[0,m] j ∈ [ 0 , n ] j\in[0,n] j[0,n] d p dp dp的大小为 ( m + 1 ) ∗ ( n + 1 ) (m+1)*(n+1) (m+1)(n+1) m = t e x t 1. l e n g t h ( ) , n = t e x t 2. l e n g t h ( ) m=text1.length(),n=text2.length() m=text1.length(),n=text2.length()
    2. i = 0 / j = 0 i=0/j=0 i=0/j=0时,表示的是 t e x t 1 text1 text1为空字符串或者 t e x t 2 text2 text2为空字符串,此时由于空字符串和任意字符串的公共子序列长度都为0,因此 d p [ i ] [ j ] = 0 i = 0 o r j = 0 dp[i][j]=0\quad i=0 orj=0 dp[i][j]=0i=0orj=0
    3. 状态转移方程:
      d p [ i ] [ j ] = { d p [ i − 1 ] [ j − 1 ] + 1 , if t e x t 1 [ i − 1 ] = t e x t 2 [ j − 1 ] m a x ( d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) , if t e x t 1 [ i − 1 ] ≠ t e x t 2 [ j − 1 ] dp[i][j]=\begin{cases} dp[i-1][j-1]+1, & \text {if\quad$text1[i-1]=text2[j-1]$} \\ max(dp[i-1][j],dp[i][j-1]), & \text{if\quad$text1[i-1]\neq text2[j-1]$} \end{cases} dp[i][j]={dp[i1][j1]+1,max(dp[i1][j],dp[i][j1]),iftext1[i1]=text2[j1]iftext1[i1]=text2[j1]
      在这里插入图片描述
class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int m = text1.length(), n = text2.length();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for (int i = 1; i <= m; i++) {
            char c1 = text1.at(i - 1);
            for (int j = 1; j <= n; j++) {
                char c2 = text2.at(j - 1);
                if (c1 == c2) {
                    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];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值