也就是lcs問題,常規的動態規劃題目,狀態轉移矩陣見下圖:
class
solution
:def
lsc(self, a, b)
: len_a, len_b =
len(a)
,len
(b)# dp[i][j]表示a的前i個數和b的前j個數構成的最長公共子串長度
dp =[[
0]*(len_b +1)
for _ in
range
(len_a +1)
]for i in
range(1
, len_a +1)
:for j in
range(1
, len_b +1)
:if a[i -1]
== b[j -1]
: dp[i]
[j]= dp[i -1]
[j -1]
+1else
: dp[i]
[j]=
max(dp[i]
[j -1]
, dp[i -1]
[j])
return dp[-1
][-1
]if __name__ ==
'__main__'
:print
(solution(
).lsc(
'13456778'
,'357486782'
))
這裡答案是5
上一步只是求出了最長公共子串行的長度,這裡要求出最長公共子串行。可以在dp的時候用乙個空間來存每一步的子串,也可以用回溯的思想來求最長公共子串行。如果是從左上角來的,就加入,如果不是就看左邊或上邊那個大的,如果相同就任選乙個方向走:
class
solution
:def
lsc(self, a, b)
: len_a, len_b =
len(a)
,len
(b)# dp[i][j]表示a的前i個數和b的前j個數構成的最長公共子串長度
dp =[[
0]*(len_b +1)
for _ in
range
(len_a +1)
]for i in
range(1
, len_a +1)
:for j in
range(1
, len_b +1)
:if a[i -1]
== b[j -1]
: dp[i]
[j]= dp[i -1]
[j -1]
+1else
: dp[i]
[j]=
max(dp[i]
[j -1]
, dp[i -1]
[j])
i, j, res = len_a, len_b,
''while i >
0and j >0:
if a[i -1]
== b[j -1]
: res = a[i -1]
+ res
i -=
1 j -=
1elif dp[i -1]
[j]> dp[i]
[j -1]
:# 上走
i -=
1else
:# 左走
j -=
1return res
if __name__ ==
'__main__'
:print
(solution(
).lsc(
'13456778'
,'357486782'
))
結果是35778,如果把
elif dp[i -1]
[j]> dp[i]
[j -1]
:# 上走
i -=
1else
:# 左走
j -=
1
變成
elif dp[i -1]
[j]>= dp[i]
[j -1]
:# 上走
i -=
1else
:# 左走
j -=
1
就又是一種結果:34678。 程式設計題 最長公共子串行
問題描述 給出兩個字串,找到最長公共子串行 lcs 返回lcs的長度。最長公共子串行的定義 最長公共子串行問題是在一組序列中找到最長公共子串行 不同於公共子串,lcs不需要是連續的子串 輸入 給出字串 abcd 和字串 edca 輸出 1 dp i 1 j 1 1 if s1 i s2 j dp i...
最長公共子串行 最長公共子串
1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...
最長公共子串行 最長公共子串
1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...