Skip to content

Commit 990d56f

Browse files
committed
Distinct Subsequences Solution Write-up
1 parent 393fc20 commit 990d56f

File tree

1 file changed

+104
-9
lines changed

1 file changed

+104
-9
lines changed

src/distinctSubsequences/distinctSubsequences.cpp

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,112 @@
1717
*
1818
*
1919
**********************************************************************************/
20-
20+
#include <stdlib.h>
21+
#include <time.h>
2122
#include <string.h>
2223
#include <iostream>
2324
#include <string>
2425
#include <map>
2526
#include <vector>
2627
using namespace std;
2728

29+
//=====================
30+
// Dynamic Programming
31+
//=====================
32+
//
33+
// The idea as below:
34+
//
35+
// Considering m[i][j] means the distance from T[i] to S[j], and add the empty "" case, then,
36+
//
37+
// A) Initialization for empty case: m[0][j] = 1;
38+
//
39+
// B) Calculation
40+
//
41+
// a) Target-len > Source-len cannot found any substring
42+
// i > j : m[i][j] = 0;
43+
//
44+
// b) if not equal, take the value of T[i] => S[j-1] (e.g. ["ra" => "rabb"] =["ra" => "rab"] )
45+
// S[j] != T[i] : m[i][j] = m[i][j-1]
46+
//
47+
// c) if equal. (e.g. ["rab" => "rabb"] = ["rab" =>"rab"] + ["ra" => "rab"] )
48+
// S[j] == T[i] : m[i][j] = m[i][j-1] + m[i-1][j-1]
49+
//
50+
// 1) Initialize a table as below
51+
// "" r a b b b i t
52+
// "" 1 1 1 1 1 1 1 1
53+
// r
54+
// b
55+
// t
56+
//
57+
// 2) Calculation
58+
// "" r a b b b i t
59+
// "" 1 1 1 1 1 1 1 1
60+
// r 0 1 1 1 1 1 1 1
61+
// b 0 0 0 1 2 3 3 3
62+
// t 0 0 0 0 0 0 0 3
63+
//
64+
int numDistinct1(string S, string T) {
65+
vector< vector<int> > m(T.size()+1, vector<int>(S.size()+1));
66+
67+
for (int i=0; i<m.size(); i++){
68+
for (int j=0; j<m[i].size(); j++){
69+
70+
if (i==0){
71+
m[i][j] = 1;
72+
continue;
73+
}
74+
if ( i>j ) {
75+
m[i][j] = 0;
76+
continue;
77+
}
78+
if (S[j-1] == T[i-1]){
79+
m[i][j] = m[i][j-1] + m[i-1][j-1];
80+
} else {
81+
m[i][j] = m[i][j-1] ;
82+
}
83+
}
84+
}
85+
return m[T.size()][S.size()];
86+
}
2887

29-
//Dynamic Programming
30-
int numDistinct(string S, string T) {
88+
89+
//=====================
90+
// Dynamic Programming
91+
//=====================
92+
//
93+
// The idea here is an optimization of above idea
94+
// (It might be difficult to understand if you don't know the above idea)
95+
//
96+
// For example:
97+
//
98+
// S = "abbbc" T="abb"
99+
// posMap = { [a]={0}, [b]={1,2} }
100+
// numOfSubSeq = {1, 0, 0, 0 }
101+
//
102+
// S[0] is 'a', pos is 0, numOfSubSeq = {1, 0+1, 0, 0};
103+
//
104+
// S[1] is 'b', pos is 2, numOfSubSeq = {1, 1, 0, 0+0};
105+
// pos is 1, numOfSubSeq = {1, 1, 0+1, 0};
106+
//
107+
// S[2] is 'b', pos is 2, numOfSubSeq = {1, 1, 1, 0+1};
108+
// pos is 1, numOfSubSeq = {1, 1, 1+1, 1};
109+
//
110+
// S[3] is 'b', pos is 2, numOfSubSeq = {1, 1, 2, 2+1};
111+
// pos is 1, numOfSubSeq = {1, 1, 1+2, 3};
112+
//
113+
// S[4] is 'c', not found, numOfSubSeq = {1, 1, 3, 3};
114+
//
115+
//
116+
int numDistinct2(string S, string T) {
31117

32118
map< char, vector<int> > pos_map;
33119
int len = T.size();
34-
int *numOfSubSeq = new int[len+1];
35-
memset(numOfSubSeq, 0, sizeof(int) * (len+1) );
120+
vector<int> numOfSubSeq(len+1);
36121
numOfSubSeq[0] = 1;
37122

38123
for (int i=len-1; i>=0; i--){
39124
pos_map[T[i]].push_back(i);
40125
}
41-
42126

43127
for (int i=0; i<S.size(); i++){
44128
char ch = S[i];
@@ -50,11 +134,22 @@ int numDistinct(string S, string T) {
50134
}
51135
}
52136

53-
int result = numOfSubSeq[len];
54-
delete[] numOfSubSeq;
55-
return result;
137+
return numOfSubSeq[len];
56138
}
57139

140+
141+
//random invoker
142+
int numDistinct(string S, string T) {
143+
srand(time(0));
144+
if (rand()%2){
145+
cout << "-----Dynamic Programming Method One-----" << endl;
146+
return numDistinct1(S,T);
147+
}
148+
cout << "-----Dynamic Programming Method Two-----" << endl;
149+
return numDistinct2(S,T);
150+
}
151+
152+
58153
int main(int argc, char** argv)
59154
{
60155
string s = "rabbbit";

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy