标签:style blog class code java c
Given a string S and a string T, count the number of distinct subsequences of T in S.
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).
Here is an example:
S = "rabbbit", T = "rabbit"
Return 3.
题意有点歧义。其实是要求S中有多少个不同的子串等于T。
dfs的思路很好写,就是从s查到*t,如果找到了,再从s+1中去找*(t+1),直到最后t为空。
1 class Solution { 2 public: 3 int numDistinct(string S, string T) { 4 count = 0; 5 dfs(S.c_str(), T.c_str()); 6 return count; 7 } 8 9 void dfs(const char* s, const char* t) { 10 if (*s == ‘\0‘) return; 11 if (*t == ‘\0‘) { 12 count++; 13 return; 14 } 15 const char* p = s-1; 16 while ((p = strchr(p+1, *t)) != NULL) { 17 dfs(p, t+1); 18 } 19 } 20 private: 21 int count; 22 };
dfs对大数据会超时。仔细分析一下,分发现其实有许多重复计算。比如s="ccaaa", t="ca"。计算第一个c之后,会dfs到后面3个a的情况。然后回溯到第二个c的时候,又会再dfs到后面3个a。于是可以用dp来做。
用nums[i][j]表示t[i...t.length-1]和s[j...s.length-1]有多少个Distinct Subsequences。我们最终求解就是nums[0][0]。
1. 如果t[i] = s[j],那么nums[i][j]应该等于t[i...t.length-1]和s[j+1...s.length-1]的数目,还要加上前一个字符累计的数目,也就是t[i+1...t.length-1]和s[j+1...s.length-1]的数目。比如t="ca", s="ccaaa"。nums[0][1]=3,t[0]=s[0],那么nums[0][0]应该就等于"ca"和“caaa”的数目(nums[0][1]),加上“a"和”caaa“之间的数目(nums[1[1]),所以nums[0][0]=nums[0][1]+nums[1][1]=3+3=6;
2. 如果t[i]!=s[j],那么nums[i][j]应该等于t[i...t.length-1]和s[j+1...s.length-1]的数目。比如t="ca", s="ccaaa", t[0]!=s[2],那么nums[0][2]应该等于"ca"和”aa"的数目,nums[0][2]=nums[0][3]=0。
3. 关于初始值:
nums[t.length][j...s.length]也就是t为空时,s[j...s.length]的数目,初始值应该为1,应该s[j...s.length]中有一个子串是空串。其他初始值都为0.
比如t="ca", s="ccaaa"。nums[1][3]=nums[1][4]+nums[2][4]=(nums[1][5]+nums[2][5])+nums[2][4]=(0+1)+1=2.
1 class Solution { 2 public: 3 int numDistinct(string S, string T) { 4 if (T.empty()) return 0; 5 if (S.empty()) return 0; 6 int n1 = S.length(); 7 int n2 = T.length(); 8 vector<vector<int> > nums(n2 + 1, vector<int>(n1 + 1, 0)); 9 for (int i = 0; i <= n1; ++i) { 10 nums[n2][i] = 1; 11 } 12 for (int i = n2 - 1; i >= 0; --i) { 13 for (int j = n1 - 1; j >= 0; --j) { 14 if (T[i] == S[j]) { 15 nums[i][j] = nums[i][j + 1] + nums[i + 1][j + 1]; 16 } else { 17 nums[i][j] = nums[i][j + 1]; 18 } 19 } 20 } 21 22 return nums[0][0]; 23 } 24 };
Leetcode | Distinct Subsequences,布布扣,bubuko.com
Leetcode | Distinct Subsequences
标签:style blog class code java c
原文地址:http://www.cnblogs.com/linyx/p/3720591.html