Lintcode118 Distinct Subsequences solution 題解

【題目描述】

Given a stringSand a stringT, count the number of distinct subsequences ofTinS.

A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie,"ACE"is a subsequence of"ABCDE"while"AEC"is not).

給出字符串S和字符串T,計算S的不同的子序列中T出現的個數。

子序列字符串是原始字符串通過刪除一些(或零個)產生的一個新的字符串,並且對剩下的字符的相對位置沒有影響。(比如,“ACE”是“ABCDE”的子序列字符串,而“AEC”不是)。

【題目鏈接】

http://www.lintcode.com/en/problem/distinct-subsequences/

【題目解析】

這道題目是一道比較基礎的動態規劃題目,關鍵問題在理解題意和恰當的設計狀態並列出狀態轉移方程。關於狀態的設立,主要還是分析題目的步驟,規劃階段,然後將每個階段的結束視爲一個狀態,來進行設立。

對於這道題目,我們不妨設f(i, j)表示S長度爲i的前綴和T長度爲j的前綴形成的兩個字符串在這道題目下的答案是多少,即設S(i)表示S長度爲i的前綴,T(j)表示T長度爲j的前綴,則f(i, j)表示有多少個S(i)的子序列等價於T(j)。那麼我們要求解的答案就可以用f(N, M)來表示,其中N是S的長度,M是T的長度。

那麼如何求解f(i, j)呢?這就要牽涉到狀態轉移方程。

我們的目標是將f(i, j)轉化爲一個類似的子問題,爲了達成這種情況,一種思路枚舉與j匹配的最後一個字符,不放設爲S的第k個字符(K<=i),則有:

f(i, j) = sum(f(k - 1, j - 1)), 其中k滿足1<=k<=i,S[k]=T[j]

從而,將f(i, j)轉化爲了若干個規模變小(兩個參數都變小)的問題,於是就可以列用這樣的狀態轉移方程進行求解:

按照i,j分別從小到大的順序,依次求解f(i, j),這樣在求解時,就可以確保其依賴的所有子問題都已經得到了求解。

但是這樣還並沒有達到這道題目的最優複雜度,不難發現,sum(f(k - 1, j - 1)), 1<=k

這樣一來,狀態轉移的複雜度就縮減到了O(1),加上狀態本身的O(NM)的複雜度,總共是O(NM)的複雜度。

【參考答案】

http://www.jiuzhang.com/solutions/distinct-subsequences/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章