最长公共子序列(LCS)C++版递归算法实现

最长公共子序列(LCS)递归算法实现


一、最长公共子序列问题

描述:给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。如果不存在公共子序列 ,则返回 0 。
注意:一个字符串的子序列是指将原字符串抽出一些字符(抽出的字符的相对顺序不发生改变)后组成新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。
两个字符串的公共子序列是这两个字符串所共同拥有的子序列。

二、解题思路

俗话说的好,人理解迭代,神理解递归。
对于序列A[0,n],B[0,n],LCS(A,B)无非三种情况:
0)n<=0或m<=0,则结果为空序列,返回0(这其实就是递归基);
1)A[n] = ‘x’ = B[m],则返回LCS(A[0,n),B[0,m))+‘x’;因为x是他们公共子序列的一部分,所以可以记录下来,同时将原字符串都减去这个x,将问题简化(减而治之);
2)A[n]≠B[m],则返回LCS(A[0,n],B[0,m))与LCS(A[0,n),B[0,m])的更长者;因为两字符串的末尾都不相同,则最少有一个字符串末尾的字符对最长公共子序列没有贡献,所以可以删掉这个字符,将问题简化(减而治之与分而治之——递归的思路);

三、代码实现

C++

代码如下:

class Solution {
public:
    int LCS(string text1, string text2) {
        if (text1.size() == 0 || text2.size() == 0)
        {
            return 0;
        }
        int len1=text1.size(),len2 = text2.size();
        if(text1[len1-1]==text2[len2-1])
        {
            text1.pop_back();
            text2.pop_back();
            return LCS(text1,text2)+1;
        }
        else
        {
            string text11 = text1;
            text11.pop_back();
            string text22 = text2;
            text22.pop_back();
            return LCS(text11,text2)>LCS(text1,text22) ? LCS(text11,text2) : LCs(text1,text22) ;
        }

    }
};

四、复杂度分析

  • 思路:无论如何,每经过一次比对,原问题的规模必然可以减少。即输入的两个序列,至少其中一个的长度缩短一个单位;
  • 最好情况下(即不出现第2种情况)下,时间复杂度为O(n+m);
  • 但最关键的在于第2种情况下,即将原问题分解为两个子问题;随着分解的进行,后面的子问题可能会出现一样的情况。所以如果当n=m时,其时间复杂度为O(2^n)。

总结

感想:递归算法确实可以很好的理解问题,思路也很简单。但其效率实在是太低了,我自己测试的一个例子当我写完这篇文章时还没算出来。所以这里只是帮你更深入的理解一下递归。至于更好的算法是动态规划。如果有做的不好的地方,欢迎指出来。关注我,一起成为更好的自己吧!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值