最长公共子序列

image

导读 ^ _ ^

子序问题可以说是最常见的DP问题。

接着上期内容,接着讲子序问题中的经典问题

这期讲解最长公共子序列问题。

最长公共子序列

本题leetcode有相关链接,但是为了防止依赖于核心代码模式。我们先自己尝试用acm模式进行思考写代码。后文也给出了C++的leetcode代码。

Snipaste_2022-12-27_17-14-28.png

思路

image.png

代码实现

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1010;

int n,m;
char a[N],b[N];
int f[N][N];

int main( ) {
	scanf("%d%d",&n,&m);
	scanf("%s%s",a+1,b+1);//下标1开始输入
	
	for (int i = 1; i <= n; i++) 
	   for (int j = 1; j <= m; j++) {
	   	    f[i][j] = max(f[i - 1][j], f[i][j - 1]);
	   	    if(a[i] == b[j]) f[i][j] = max(f[i][j], f[i-1][j-1] + 1);
	   }
	
	printf("%d",f[n][m]);
	return 0;
}

leetcode题目

leetcode 1143
image.png

代码与思路

确定状态

  • dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]
  • text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同
  • text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1;
  • text1[i - 1] 与 text2[j - 1]不相同,取最大的前一个子序,dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
  • image.png

遍历答案

//最长公共子序列


class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        vector<vector<int>> dp(text1.size() + 1, vector<int>(text2.size() + 1, 0));
        for (int i = 1; i <= text1.size(); i++) {
            for (int j = 1; j <= text2.size(); 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[text1.size()][text2.size()];
    }
};

#谢谢你的观看!

原文链接: https://www.cnblogs.com/HX-Note/p/17030425.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    最长公共子序列

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/310063

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 上午11:20
下一篇 2023年2月16日 上午11:21

相关推荐