• [LintCode] Longest Common Subsequence


    给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。

    说明

    最长公共子序列的定义:

    • 最长公共子序列问题是在一组序列(通常2个)中找到最长公共子序列(注意:不同于子串,LCS不需要是连续的子串)。该问题是典型的计算机科学问题,是文件差异比较程序的基础,在生物信息学中也有所应用。
    • https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
    样例

    给出"ABCD" 和 "EDCA",这个LCS是 "A" (或 D或C),返回1

    给出 "ABCD" 和 "EACB",这个LCS是"AC"返回 2

    最长公共子序列是DP的典型例子。

    设X = <x1, x2, x3, .. . , xm>, Y = <y1, y2, y3, ... , yn> 为两个子串。

    LCS(X, Y)表示X和Y的一个最长公共子序列。则:

      1. 如果xm = yn 则 LCS(X, Y) = xm + LCS(Xm-1, Yn-1)

      2. 如果xm != yn 则 LCS(X, Y) = max{LCS(Xm-1, Y), LCS(X, Yn-1)}

    LCS问题也具有重叠子问题性质:为找出X和Y的一个LCS,可能需要找X和Yn-1的一个LCS以及Xm-1和Y的一个LCS。但这两个子问题都包含着找Xm-1和Yn-1的一个LCS,等等.

    DP最终处理的还是数值(极值做最优解),找到了最优值,就找到了最优方案;为了找到最长的LCS,我们定义dp[i][j]记录序列LCS的长度,合法状态的初始值为当序列X的长度为0或Y的长度为0,公共子序列LCS长度为0,即dp[i][j]=0,所以用i和j分别表示序列X的长度和序列Y的长度,状态转移方程为

    1. dp[i][j] = 0  如果 i = 0或 j = 0
    2. dp[i][j] = dp[i - 1][j - 1] + 1  如果X[i - 1] = Y[i - 1] (X[i - 1]就是X数组中的第i个)
    3. dp[i][j] = max{ dp[i - 1][j], dp[i][j - 1] }  如果X[i - 1] != Y[i - 1]
    class Solution {
    public:
        /*
         * @param A: A string
         * @param B: A string
         * @return: The length of longest common subsequence of A and B
         */
        int longestCommonSubsequence(string A, string B) {
            // write your code here
            int m = A.size(), n = B.size();
            if (m == 0 || n == 0)
                return 0;
            vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
            for (int i = 1; i != m + 1; i++) {
                for (int j = 1; j != n + 1; j++) {
                    if (A[i - 1] == B[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[m][n];
        }
    };
  • 相关阅读:
    如何将DataTable转换成List<T>
    关于SqlDataAdapter的使用
    VS 2010中JS代码折叠插件
    ASP.net中的几种分页方法
    学习jquery基础教程的一些笔记
    js中innerHTML与innerText的用法与区别
    SpringBoot 中使用shiro注解使之生效
    redis分布式锁
    使用ZSetOperations(有序)操作redis
    使用SetOperations(无序)操作redis
  • 原文地址:https://www.cnblogs.com/immjc/p/7435168.html
Copyright © 2020-2023  润新知