动态规划(5)-最长公共子序列
最长公共子序列
https://www.nowcoder.com/practice/6d29638c85bb4ffd80c020fe244baf11?tpId=117&tqId=37798&rp=1&ru=%2Fta%2Fjob-code-high&qru=%2Fta%2Fjob-code-high%2Fquestion-ranking&tab=answerKey
题目描述
给定两个字符串str1和str2,输出连个字符串的最长公共子序列。如过最长公共子序列为空,则输出-1。
示例1
输入
"1A2C3D4B56","B1D23CA45B6A"
返回值
"123456"
说明
"123456"和“12C4B6”都是最长公共子序列,任意输出一个。
思路
- Q1:dp数组设置?
两个字符串比较,设置dp[m+1][n+1],dp[i][j]表示字符串1[:i]和字符串2[:j]比较的结果 - Q2:状态转移方程?
一开始写成dp[i][j]=dp[i-1][j-1]+chs1[i-1]==chs2[j-1]?1:0;结果不对。
后来想到,如果不等的话,应该和dp[i][j-1],dp[i-1][j]有关.
code
import java.util.*; public class Solution { public String LCS (String s1, String s2) { char []chs1=s1.toCharArray(); char []chs2=s2.toCharArray(); int m=chs1.length,n=chs2.length; if(m==0||n==0)return "-1"; int dp[][]=new int[m+1][n+1]; int max=-1; for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ if(chs1[i-1]==chs2[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]); max = Math.max(max,dp[i][j]); } } int i=m,j=n; StringBuffer sb = new StringBuffer(); while(i!=0&&j!=0){ if(chs1[i-1]==chs2[j-1]){ sb.append(chs1[i-1]); i--;j--; }else{ int temp = dp[i-1][j]>dp[i][j-1]?i--:j--; //temp无用,只为简洁 } } if(sb.length() == 0) return "-1"; return sb.reverse().toString(); } }