leetcode 115 Distinct Subsequences
阿新 • • 發佈:2018-12-22
題目大意是給出兩個字串S和T,要求求出S中與T相匹配的子字串的數量。
子字串可以通過從S中刪除元素且不改變剩餘元素順序的方式得到。
想法1
這是個動態規劃題目,從題目的描述中其實就有陷阱,因為按照刪除方法的話很難以去構建狀態轉移方程。子字串的構建可以通過增加的方式,即每次找到一個S與T相匹配的字元,直到找齊,這個思想的遞迴解法很容易寫出來。當然,肯定會超時。
既然如此,可以按照類似的思想來構建狀態轉移方程。首先思考如何構建自狀態,考慮到T,既然要找與T相匹配的子字串,那麼能不能先找到所有與T的字首相匹配的子字串,再來找T呢?是可以的。
比如對於S=“babgbag”,T=“bag”,先考慮T="b"的情況下,這時候按照順序,S能找到的匹配個數為1 0 1 0 1 0 0
0 1 0 0 0 3 0
。當T="bag"時,有0 0 0 1 0 0 4
,顯然,答案為最後一個的所有元素之和。
因此狀態轉移函式F[i][j] 的意義為對於T的字首T[0…i],以S[j]結尾的S的字首中可以構建出的子字串的數量。
很容易有,設s.length()=n,t.length()=m,程式碼的時間複雜度為,空間複雜度為O(nm)
程式碼很快就AC了,但是耗時16ms,只超過了5%左右的C++程式碼
原始碼:
class Solution {
public:
int numDistinct(string s, string t) {
vector<int> F(s.length()*t.length(),0);
for(int i = 0;i<s.length();i++)
{
if(s[i]==t[0])
{
F[i] = 1;
}
}
for(int y = 1;y<t.length();y++)
{
for(int x = 0;x<s.length();x++)
{
int coordinate = x+y*s.length();
F[coordinate] = 0;
if(s[x]==t[y])
{
for(int k = 0;k<x;k++)
{
F[coordinate] += F[(y-1)*s.length() + k];
}
}
}
}
int sum = 0;
for(int i = 0;i<s.length();i++)
{
sum+=F[i+(t.length()-1)*s.length()];
}
return sum;
}
};