首页 > 试题广场 >

最长公共子序列(二)

[编程题]最长公共子序列(二)
  • 热度指数:116749 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如果最长公共子序列为空,则返回"-1"。目前给出的数据,仅仅会存在一个最长的公共子序列

数据范围:
要求:空间复杂度 ,时间复杂度
示例1

输入

"1A2C3D4B56","B1D23A456A"

输出

"123456"
示例2

输入

"abc","def"

输出

"-1"
示例3

输入

"abc","abc"

输出

"abc"
示例4

输入

"ab",""

输出

"-1"
垃圾题
#define max(a,b) (a>b?a:b)
char* LCS(char* s1, char* s2 ) {
    int dp[10000][10000], i, j, maxLen=0, max_i=0, max_j=0;
    
    for(i=0; i<strlen(s1); i++) {
        dp[i][0] = 0;
        if(s1[i]==s2[0]) {
            maxLen = 1;
            break;
        }
    }
    for(; i<strlen(s1); i++) {
        dp[i][0] = 1;
        max_i = i;
        max_j = 0;
    }
    
    for(j=0; j<strlen(s2); j++) {
        dp[0][j] = 0;
        if(s2[j]==s1[0]) {
            maxLen = 1;
            break;
        }
    }
    for(; j<strlen(s2); j++) {
        dp[0][j] = 1;
        max_i = 0;
        max_j = j;
    }

    for(i=1; i<strlen(s1); i++) {
        for(j=1; j<strlen(s2); j++) {
            if(s1[i]==s2[j]) {
                dp[i][j] = dp[i-1][j-1]+1;
                if(maxLen<dp[i][j]) {
                    maxLen = dp[i][j];
                    max_i = i;
                    max_j = j;
                }
            }
            else {
                dp[i][j] = max(dp[i][j-1],dp[i-1][j]);
                if(maxLen<dp[i][j]) {
                    maxLen = dp[i][j];
                    max_i = i;
                    max_j = j;
                }
            }
            
        }
    }

    char* res=(char*)malloc(maxLen+1);
    res[maxLen--]='\0';
    while(max_i>0 && max_j>0) {
        if(dp[max_i][max_j]>dp[max_i][max_j-1] && dp[max_i][max_j]>dp[max_i-1][max_j]) {
            res[maxLen--]=s1[max_i];
            max_i--, max_j--;
        }
        else if(dp[max_i][max_j]==dp[max_i][max_j-1] && dp[max_i][max_j]>dp[max_i-1][max_j]) 
            max_j--;
        else if(dp[max_i][max_j]>dp[max_i][max_j-1] && dp[max_i][max_j]==dp[max_i-1][max_j]) 
            max_i--;
        else 
            max_i--, max_j--;
    }
    
    while(max_i--)
    {
        if(dp[max_i][0]>dp[max_i-1][0]) 
            break;
    }
 
    if(max_i<0)
        max_i++;
     res[maxLen]=s1[max_i];
    
    if(strlen(res)==0)
        return "-1";

    return res;
}

编辑于 2024-03-25 23:57:36 回复(0)
(1) 查资料参考了别人的解题方法。
(2) 字符串摆放的位置和数组的行列标号非常容易混淆。一不小心方向就弄错了。
(3) 这个题有规定的返回值,调试信息printf()保留了也没有影响。
(4) 得到的字符串再反转1次才是最终结果。
发表于 2023-03-05 14:50:29 回复(0)