最长公共子串(动态规划)

题目

题目描述 给定两个字符串str1和str2,输出两个字符串的最长公共子串 题目保证str1和str2的最长公共子串存在且唯一。 示例1
输入"1AB2345CD",“12345EF” 返回值 “2345”

思路

动态规划的典型例子,要想好状态怎么变化。

在这里用二维数组保存状态,假设 字符串为 123 ,12 。
则有一开始状态:

*123
1
2

然后

123
10+1=100
201+1=20

所以对于一个格子状态判断是这样的:

  • 若两个字符相同,状态为左上角格子状态+1
  • 若两个字符不同,状态归0 (因为子串要求连续

代码

class Solution {
public:
    /**
     * longest common substring
     * @param str1 string字符串 the string
     * @param str2 string字符串 the string
     * @return string字符串
     */
        
    string LCS(string str1, string str2) {
        // write code here
        int len1 = str1.size();
        int len2 = str2.size();
        
        //if(len1<len2) swap(str1,str2);   
       
        int **map;
        map = new int* [len2+1];
        for(int i=0;i<=len2;i++){
            map[i] = new int[len1+1];
        }
        for(int i=0;i<=len2;i++){
            for(int j=0;j<=len1;j++){
                map[i][j] = 0;
            }
        }
        
        int maxj=0,maxlen=0;
        
        for(int i=1;i<=len2;i++){
            
            for(int j=1;j<=len1;j++){
                
                if(str2[i-1] == str1[j-1]){
                    map[i][j] = map[i-1][j-1]+1;//相等记录为左上角+1
                    if(maxlen < map[i][j]){//需要更新max
                        maxj = j;
                        maxlen = map[i][j];
                    }
                   // cout<<i<<endl;
                }
                else{
                     map[i][j] = 0 ;//不相等归0
                }
            }
        }
        
       auto res = str1.substr(maxj-maxlen,maxlen);
       return res;
    }
};

类比一下差不多的题目,最长公共子序列。
子序列不要求相同的字母连续出现
所以一个格子的状态变换为:

  • 若两个字符相同,取左上角状态+1或左边状态中最大那个为自己状态
  • 若不同,则取左边格子状态为自己状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值