87. Scramble String (String; DP)
2015-10-30 18:59
302 查看
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 =
To scramble the string, we may choose any non-leaf node and swap its two children.
For example, if we choose the node
We say that
Similarly, if we continue to swap the children of nodes
We say that
Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.
思路:对付复杂问题的方法是从简单的特例来思考。简单情况:
如果字符串长度为1,那么必须两个字符串完全相同;
如果字符串长度为2,例如s1='ab',则s2='ab'或s2='ba'才行
如果字符串任意长度,那么可以把s1分为a1, b1两部分,s2分为a2,b2两部分。需要满足:((a1=a2)&&(b1=b2)) || ((a1=b2)&&(a2=b1)) =>可用递归
Result: Time Limit Exceeded
思路II: 动态规划。三维状态dp[i][j][k],前两维分别表示s1和s2的下标起始位置,k表示子串的长度。dp[i][j][k]=true表示s1(i, i+k-1)和s2(j, j+k-1)是scramble。
Below is one possible representation of s1 =
"great":
great / \ gr eat / \ / \ g r e at / \ a t
To 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 t
We 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 a
We 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.
思路:对付复杂问题的方法是从简单的特例来思考。简单情况:
如果字符串长度为1,那么必须两个字符串完全相同;
如果字符串长度为2,例如s1='ab',则s2='ab'或s2='ba'才行
如果字符串任意长度,那么可以把s1分为a1, b1两部分,s2分为a2,b2两部分。需要满足:((a1=a2)&&(b1=b2)) || ((a1=b2)&&(a2=b1)) =>可用递归
class Solution { public: bool isScramble(string s1, string s2) { if(s1 == s2) return true; for(int isep = 1; isep < s1.size(); ++ isep) { //traverse split pos string seg11 = s1.substr(0,isep); string seg12 = s1.substr(isep); //see if a1=a2 &&b1=b2 is ok string seg21 = s2.substr(0,isep); string seg22 = s2.substr(isep); if(isScramble(seg11,seg21) && isScramble(seg12,seg22)) return true; //see if a1=b2 &&a2=b1 is ok seg21 = s2.substr(s2.size() - isep); //从后截取isep长度 seg22 = s2.substr(0,s2.size() - isep); if(isScramble(seg11,seg21) && isScramble(seg12,seg22)) return true; } return false; } };
Result: Time Limit Exceeded
思路II: 动态规划。三维状态dp[i][j][k],前两维分别表示s1和s2的下标起始位置,k表示子串的长度。dp[i][j][k]=true表示s1(i, i+k-1)和s2(j, j+k-1)是scramble。
class Solution { public: bool isScramble(string s1, string s2) { int len = s1.length(); if(len==0) return true; if(s1 == s2) return true; //初始状态 vector<vector<vector<bool>>> dp(len, vector<vector<bool>>(len, vector<bool>(len+1, false) ) ); for (int i = 0; i < len; ++i) { for (int j = 0; j < len; ++j) { dp[i][j][1] = s1[i]==s2[j]; } } //状态转移 for(int levelSize = 2; levelSize <= len; levelSize++) //从较短的子串开始分析,为了状态转方程 { for(int s1Pointer = 0; s1Pointer+levelSize-1 < len; s1Pointer++) { for(int s2Pointer = 0; s2Pointer+levelSize-1 < len; s2Pointer++) { for(int split = 1; split < levelSize; split++) //levelSize长度的任意一种分割 { if ((dp[s1Pointer][s2Pointer][split] && dp[s1Pointer+split][s2Pointer+split][levelSize-split]) || (dp[s1Pointer][s2Pointer+levelSize-split][split] && dp[s1Pointer+split][s2Pointer][levelSize-split])) { dp[s1Pointer][s2Pointer][levelSize] = true; break; }; } } } } return dp[0][0][len]; } };
相关文章推荐
- 华为认证和思科认证,哪一款适合你?
- STL-综合示例
- STL-泛型算法示例
- STL-初始化实验
- STL-访问向量信息
- STL-向量插入/删除
- STL-vector中reserve和resize的区…
- STL-list的访问与遍历
- STL-list插入与删除
- STL-list成员的删除
- STL-list存储格式探究
- STL-list中的spilce()
- STL-list中的merge()
- STL-stack
- STL-单向队列queue
- FTM的PWM、输入捕获、正交解码
- 当程序猿修真,这个世界会怎样!
- 易经的数学模型
- 货币数字转换为中文大写格式
- cmd&nbsp;组合命令和管道命令的使用