0
点赞
收藏
分享

微信扫一扫

4.8分钟学会 最长公共子序列(内附C++源码,直接运行的那种)

吴wuwu 2022-03-11 阅读 60

算法这个东西真的很奇妙,学了之后很容易使人上瘾,当然,是在简单的前提下这么说的,如果遇到那种难题,我也是很头疼。

今天的剧情依然是老师跟学生的对答形式,这样我觉得更循序渐进一些,不会那么突兀,你觉得呢?

来,同学们,先看老师的课件上两道题:

第一题:给两个整数数组 A 和 B ,返回两个数组中公共的、长度最长的子数组的长度。

示例:

输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出:3 解释: 长度最长的公共子数组是 [3, 2, 1] 。

第二题:给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。

例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。

若这两个字符串没有公共子序列,则返回 0。

示例 1:

输入:text1 = "abcde", text2 = "ace"
输出:3
解释:最长公共子序列是 "ace",它的长度为 3。

以上是两道题目,给大家5分钟时间请同学们观察两道题目的里面的相同点和不同点。

5分钟时间到,小松,你来回答不同点。

我认为第一题是强调的只有连续的子序列相同才会持续计数,如果前面一系列序列相同,到下一个元素不相同时就从0开始计数了,但是还得需要重新定义一个变量来接收上一个最大子序列的长度;而第二题是无论持续还是不持续,只要text2中的字母顺序与text1中相同的字母顺序是一致的,那么就可以持续计数,所以这个第二题并不强调连续。

大家说小松回答的怎么样啊?

非常好,那谁来回答一下共同点呢?

这次小刚自告奋勇的举起手来,我说吧老师,快让我说,憋死我了

好,那就小刚你来说。

这题我会,通过上次的程序中我总结了,只要是求最长***子序列,那肯定就得遍历,而且这两道题目都是分别给了两个组,而且都是在第一个组中找第二个组中相同元素的个数,只不过第一题强调连续,第二题不强调连续。”

啊?(老师一脸惊讶)这小刚刚来啊,这也变化太快了吧

呵呵 主要是老师教的好,没办法

好,不错,那谁来说一说这两道题目的代码是什么,需要能直接运行的哦

行,那就小丽说第一题,小绿做第二题吧。

#include <iostream>
#include <vector>
using namespace std;
int findLength(vector<int>& nums1,vector<int>& nums2)
{
    vector<vector<int>>dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
    int result=0;
    for(int i=1;i<=nums1.size();++i)
    {
        for(int j=1;j<=nums2.size();j++)
        {
            if(nums1[i-1]==nums2[j-1])
            {
                dp[i][j]=dp[i-1][j-1]+1;
                if(dp[i][j]>result)
                result=dp[i][j];
            }
        }
    }
    return result;
}
int main()
{
    vector<int> num1={1,2,3,2,1};
    vector<int> num2={3,2,1,4,7};
    int ret=findLength(num1,num2);
    cout<<"ret="<<ret<<endl;
    return 0;
}

老师,我解释一下,dp[i][j]是由他们的上一组相同元素所处的值加1得到的。

这一题我做完了,我算出来的结果是3.

其他同学第一题做出来了嘛,等于多少啊,3(异口同声),不错啊

#include <iostream>
#include <vector>
using namespace std;
int findLength(string& text1,string& text2)
{
    vector<vector<int>>dp(text1.size()+1,vector<int>(text2.size()+1,0));
    int result=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][j-1],dp[i-1][j]);    
            }
                if(dp[i][j]>result)
                result=dp[i][j];
        }
    }
    return result;
}
int main()
{
    string text1="abcde";
    string text2="ace";
    int ret=findLength(text1,text2);
    cout<<"ret="<<ret<<endl;
    return 0;
}

老师,我来解释一下:

当text1[i-1] != text2[j-1]时,分别对text1和text2的上一个元素时的值求最大值。

这次我运行的结果也是3。

其他同学有不一样的嘛?都一样(异口同声)   不错哦!

举报

相关推荐

最长公共子序列 DP C++

0 条评论