给出两个字符串,找到最长公共子序列(LCS),返回LCS的长度。
您在真实的面试中是否遇到过这个题? 是
最长公共子序列的定义:
给出"ABCD" 和 "EDCA",这个LCS是 "A" (或 D或C),返回1
给出 "ABCD" 和 "EACB",这个LCS是"AC"返回 2
这一题很有意思,和公共子串我会连着讲。
思路其实也不难,设A数组长m,B数组长n,则:
dp数组为m*n,dp[i][j]代表A数组前i个数和B数组前j个数的最长子序列长度
那么我们就有了递推式:
dp[i][j]=dp[i-1][j-1]+1 if A[i]==B[j] and i>0 and j>0
dp[i][j]= max( dp[i-1][j],dp[i][j-1] ) if A[i]!=B[j] and i>0 and j>0
当然需要注意的一点是,初始化第0行和第0列的时候需要把出现了相等后的所有数初始化为1,具体看代码里:
class Solution:
"""
@param A: A string
@param B: A string
@return: The length of longest common subsequence of A and B
"""
def longestCommonSubsequence(self, A, B):
# write your code here
m, n = len(A), len(B)
if(m==0 or n==0): return 0
# dp数组为m*n,dp[i][j]代表A数组前i个数和B数组前j个数的最长子序列长度
dp=[[0 for i in range(n)] for j in range(m)]
# 初始化第一行和第一列
index=m+n #记录第几个数是相等的,取m+n是为了保持比i大
for i in range(m):
if(A[i]==B[0] or index<=i):
dp[i][0]=1
index=i
index =m+n # 记录第几个数是相等的
for i in range(n):
if(B[i]==A[0] or index<=i):
dp[0][i]=1
index=i
# 开始递推
for i in range(1,m):
for j in range(1,n):
if(A[i]==B[j]):
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-1][n-1]
s = Solution()
print(s.longestCommonSubsequence([1,2],[1,4,2,3]))