码迷,mamicode.com
首页 > 其他好文 > 详细

求最长公共子序列-DP问题

时间:2019-03-18 12:00:18      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:const   top   while   fir   use   each   ram   and   return   

Longest common subsequence problem

The longest common subsequence (LCS) problem is the problem of finding the longest subsequence common to all sequences in a set of sequences (often just two sequences). It differs from the longest common substring problem: unlike substrings, subsequences are not required to occupy consecutive positions within the original sequences.

Example

  • LCS for input Sequences ABCDGH and AEDFHR is ADH of length 3.
  • LCS for input Sequences AGGTAB and GXTXAYB is GTAB of length 4

以s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2}为例。

1.构建二维矩阵A[n+1][n+1] s1为列,s2为行

(1)A[0][any]=0,A[any][0]=0

(2)if(s1[columnIndex-1]==s2[rowIndex-1])则A[rowIndex][columnIndex]=A[rowIndex-1][columnIndex-1]+1;

         else  A[rowIndex][columnIndex]=max(A[rowIndex][columnIndex-1],A[rowIndex-1][columnIndex])

 (3)由A[8][9]可知最大子序列长度。

图如下:

 技术图片

 2.针对构建的二维矩阵求最长子序列

(1)当columnIndex>0或者rowIndex>0时。

(2)如果s1[columnIndex-1]==s2[rowIndex-1]则longestSequence.unshift(s1[columnIndex-1]).rowIndex--;columnIndex--.

(3)如果不等,

              则1.如果A[rowIndex][columnIndex]==A[rowIndex][columnIndex-1];columnIndex--;//向左

      2.否则 rowIndex--;

 技术图片

 

代码如下:

 

/**
 * @param {string[]} set1
 * @param {string[]} set2
 * @return {string[]}
 */
export default function longestCommonSubsequence(set1, set2) {
  // Init LCS matrix.
  const lcsMatrix = Array(set2.length + 1).fill(null).map(() => Array(set1.length + 1).fill(null));

  // Fill first row with zeros.
  for (let columnIndex = 0; columnIndex <= set1.length; columnIndex += 1) {
    lcsMatrix[0][columnIndex] = 0;
  }

  // Fill first column with zeros.
  for (let rowIndex = 0; rowIndex <= set2.length; rowIndex += 1) {
    lcsMatrix[rowIndex][0] = 0;
  }

  // Fill rest of the column that correspond to each of two strings.
  for (let rowIndex = 1; rowIndex <= set2.length; rowIndex += 1) {
    for (let columnIndex = 1; columnIndex <= set1.length; columnIndex += 1) {
      if (set1[columnIndex - 1] === set2[rowIndex - 1]) {
        lcsMatrix[rowIndex][columnIndex] = lcsMatrix[rowIndex - 1][columnIndex - 1] + 1;
      } else {
        lcsMatrix[rowIndex][columnIndex] = Math.max(
          lcsMatrix[rowIndex - 1][columnIndex],
          lcsMatrix[rowIndex][columnIndex - 1],
        );
      }
    }
  }

  // Calculate LCS based on LCS matrix.
  if (!lcsMatrix[set2.length][set1.length]) {
    // If the length of largest common string is zero then return empty string.
    return [‘‘];
  }

  const longestSequence = [];
  let columnIndex = set1.length;
  let rowIndex = set2.length;

  while (columnIndex > 0 || rowIndex > 0) {
    if (set1[columnIndex - 1] === set2[rowIndex - 1]) {
      // Move by diagonal left-top.
      longestSequence.unshift(set1[columnIndex - 1]);
      columnIndex -= 1;
      rowIndex -= 1;
    } else if (lcsMatrix[rowIndex][columnIndex] === lcsMatrix[rowIndex][columnIndex - 1]) {
      // Move left.
      columnIndex -= 1;
    } else {
      // Move up.
      rowIndex -= 1;
    }
  }

  return longestSequence;
}

 

求最长公共子序列-DP问题

标签:const   top   while   fir   use   each   ram   and   return   

原文地址:https://www.cnblogs.com/Archer-Fang/p/10551181.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!