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 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.
个人觉得这道题真是挺难的,做了两个晚上,最后看了别人的解法,思路在注释里:
class Solution {
public:
/*************************************************************************
** 思路:1)最初想到的是如果两个字符串能够通过题目给出的交换方式的到,
** 那么对两个字符串进行排序,如果排序结果相同,则证明两个字符串
** 就满足要求返回true,结果提交,果断贡献WA,原因是排序相等只是
** scramble 的必要非充分条件
** 2)递归思路,字符串s1和s2是scramble的充分必要条件是:
** s1.compare(s2)=0 or
** ( s1.substr(0,i)和s2.substr(0,i)是scramble and s1.substr(i+1,len-i)和s2.substr(i+1,len-i)是scramble) or
** (s1.substr(0,i)和s2.substr(len-i+1,i)是scramble and s1.substr(i+1,len-i)和s2.substr(0,len-i)是scramble )
** 由此对于两个字符串s1和s2存在len-1中分割选择,但是递归到下层时会存在大量重复计算
** 3) 为了避免重复计算,使用动态规划,按照2)中描述的递归式,申
** 请三维dp数组dp[len][len][len],第一维表示字符串s1的起点,第二维表
** 示s2的起点,第三维表示字串的长度,最终结果表示为dp[0][0][len]
*************************************************************************/
bool isScramble(string s1, string s2) {
int len=s1.size();
if (len==0){
return true;
}
vector <vector <vector <bool>>> dp(len,vector<vector<bool>>(len,vector<bool>(len,false)));
//initialization dp
for(int i=0;i<len;i++){
for(int j=0;j<len;j++){
if(s1[i]==s2[j]){
dp[i][j][0]=true;
}
}
}
//dp
for(int l=2;l<=len;l++){
for(int i=0;i+l<=len;i++){
for(int j=0;j+l<=len;j++){
// k partations
for (int k=1;k<l;k++){
if ((dp[i][j][k-1]&&dp[i+k][j+k][l-k-1])||
dp[i][j+k][l-k-1]&&dp[i+l-k][j][k-1]){
dp[i][j][l-1]=true;
break;
}
}
}
}
}
return dp[0][0][len-1];
}
};