动态规划 最长公共子序列

125 阅读1分钟

题目

给定两个字符串,求两个字符串的最长公共子序列

  • 遍历模型为遍历所有子串,动态规划表 dp[i][j],i、j表示以 i、j 结尾的子串 ,对 i、j 结尾的公共子序列进行可能性分析,分为四种可能性
    • 公共子序列位置和 i、j位置无关
    • 公共子序列位置以 i 结尾,不以 j 结尾
    • 公共子序列位置以 j 结尾,不以 i 结尾
    • 公共子序列位置以 i、j结尾,那么为 1+ (i-1,j-1)位置的值
function process(str1, str2) {
  let res = 0,
    dp = [],
    row = str1.length,
    col = str2.length;

  for (let i = 1; i < row; i++) {
    for (let j = 1; j < col; j++) {
    
      res = dp[i - 1][j - 1] || 0; // 子序列和i、j位置无关
      res = Math.max(res, dp[i - 1][j] || 0); // 子序列以j结尾,不以i结尾
      res = Math.max(res, dp[i][j - 1] || 0); // 子序列以i结尾,不以j结尾 
      
      if (str1[i]== str2[j]) {
        res = Math.max(res, (dp[i - 1][j - 1] || 0) + 1); // 如果相等,则子序列为 dp[i-1][j-1] 位置的值 + 1
      }
      dp[i][j] = res;
    }
  }

  return dp[row-1][col-1]; // 最长公共子序列一定存在两个字符串结尾位置中
}