Scramble String
Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.Below is one possible representation of s1 =
"great"
:
great / \ gr eat / \ / \ g r e at / \ a tTo scramble the string, we may choose any non-leaf node and swap its two children.
For example, if we choose the node
"gr"
and swap its two children, it produces a scrambled string "rgeat"
.
rgeat / \ rg eat / \ / \ r g e at / \ a tWe say that
"rgeat"
is a scrambled string of "great"
.
Similarly, if we continue to swap the children of nodes
"eat"
and "at"
, it produces a scrambled string "rgtae"
.
rgtae / \ rg tae / \ / \ r g ta e / \ t aWe say that
"rgtae"
is a scrambled string of "great"
.
Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.
-------------------------------------------------------------
Solution #1 recursive
bool scramble(string s1,string s2) { if (s1 == s2) return true; string t1 = s1,t2 = s2; sort(t1.begin(),t1.end()); sort(t2.begin(),t2.end()); if (t1 != t2) return false; for (int i = 1; i < s1.length(); i++) { string p1 = s1.substr(0,i), p2 = s1.substr(i); string q1 = s2.substr(0,i), q2 = s2.substr(i); string q3 = s2.substr(s2.length() - i), q4 = s2.substr(0,s2.length() - i); if ((scramble(p1,q1) && scramble(p2,q2)) || (scramble(p1,q3) && scramble(p2,q4))) return true; } return false; }
Solution #2 recursive + memo
找出s1所有的scrambled strings,然后一一对比
class Solution { public: unordered_map<string,vector<string>> dic; void combine(vector<string> &rt,vector<string> &v1,vector<string> &v2) { for (string s1 : v1) { for (string s2 : v2) { rt.push_back(s1 + s2); rt.push_back(s2 + s1); } } } vector<string> permutation(string s) { vector<string> rt; if (s.length() == 1) { rt.push_back(s); } for (int i = 1; i < s.length(); i++) { string s0 = s.substr(0,i); string s1 = s.substr(i); vector<string> v1,v2; if (dic.find(s0) != dic.end()) { v1 = dic[s0]; }else { v1 = permutation(s0); dic[s0] = v1; } if (dic.find(s1) != dic.end()) { v2 = dic[s1]; }else { v2 = permutation(s1); dic[s1] = v2; } combine(rt,v1,v2); } return rt; } bool isScramble(string s1, string s2) { vector<string> rt = permutation(s1); for (string s : rt) { if (s == s2) return true; } return false; } };
Solution #3 3-dimensional DP
dp[length][index at s1][index at s2]
int the most inner loop, delimiter breaks string in k - 1 different ways. same logic as recursive
注意loop里的终止条件
class Solution { public: bool isScramble(string s1, string s2) { int len = s1.length(); vector<vector<vector<bool> > > dp(len,vector<vector<bool> >(len,vector<bool>(len,false))); for (int i = 0; i < len; i++) { for (int j = 0; j < len; j++) { if (s1[i] == s2[j]) { dp[0][i][j] = true; } } } for (int k = 2; k <= len; k++) { for (int i = 0; i <= len - k; i++) { for (int j = 0; j <= len - k; j++) { for (int delimiter = 1; delimiter < k; delimiter++) { if (dp[delimiter - 1][i][j] && dp[k - delimiter - 1][i + delimiter][j + delimiter]) { dp[k - 1][i][j] = true; break; } if (dp[delimiter - 1][i][j + k - delimiter] && dp[k - delimiter - 1][i + delimiter][j]) { dp[k - 1][i][j] = true; break; } } } } } return dp[len - 1][0][0]; } };
No comments:
Post a Comment