【題目描述】
Given two strings, find the longest common subsequence (LCS).
Your code should return the length ofLCS.
給出兩個字符串,找到最長公共子序列(LCS),返回LCS的長度。
【題目鏈接】
www.lintcode.com/en/problem/longest-common-subsequence/
【題目解析】
求最長公共子序列的數目,注意這里的子序列可以不是連續序列,務必問清楚題意。求『最長』類的題目往往與動態規劃有點關系,這里是兩個字符串,故應為雙序列動態規劃。
這道題的狀態很容易找,不妨先試試以f[i][j]表示字符串A 的前i位和字符串 B 的前j位的最長公共子序列數目,那么接下來試試尋找其狀態轉移方程。從實際例子ABCD和EDCA出發,首先初始化f的長度為字符串長度加1,那么有f[0][0] = 0,f[0][*] = 0,f[*][0] = 0, 最后應該返回f[lenA][lenB]. 即 f 中索引與字符串索引對應(字符串索引從1開始算起),那么在A 的第一個字符與 B 的第一個字符相等時,f[1][1] = 1 + f[0][0], 否則f[1][1] = max(f[0][1], f[1][0])。
推而廣之,也就意味著若A[i] == B[j], 則分別去掉這兩個字符后,原 LCS 數目減一,那為什么一定是1而不是0或者2呢?因為不管公共子序列是以哪個字符結尾,在A[i] == B[j]時LCS 最多只能增加1. 而在A[i] != B[j]時,由于A[i]或者B[j]不可能同時出現在最終的 LCS 中,故這個問題可進一步縮小,f[i][j] = max(f[i - 1][j], f[i][j - 1]). 需要注意的是這種狀態轉移方程只依賴最終的 LCS 數目,而不依賴于公共子序列到底是以第幾個索引結束。
【參考答案】