问题描述
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"
:
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"
.
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"
.
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.
Example 1:
Input: s1 = "great", s2 = "rgeat" Output: true
Example 2:
Input: s1 = "abcde", s2 = "caebd" Output: false
题目大意就是判断s2能够由s1的树反转得到。
解题思路:
递归的思想,每次从中间分开,查看左右能否满足条件,或者交叉满足条件。因为不知道从哪里分开,所以就需要遍历,核心代码如下:
for(int i=1; i<N; i++){
if(isScramble(s1.substr(0,i), s2.substr(0,i)) && isScramble(s1.substr(i), s2.substr(i)))
return true;
if(isScramble(s1.substr(0,i), s2.substr(N-i)) && isScramble(s1.substr(i), s2.substr(0, N-i)))
return true;
}
两个判断的意思就是s1,s2左,s1,s2右能满足条件。或者s1左s2右,s1右s2左能满足条件。
跳出递归的条件如下:
if(s1.length() != s2.length()) return false;
int N = s1.length();
if(N==0) return true;
if(N==1) return s1==s2;
程序源码:
class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1.length() != s2.length()) return false;
int N = s1.length();
if(N==0) return true;
if(N==1) return s1==s2;
string s1cpy = s1;
string s2cpy = s2;
sort(s1cpy.begin(), s1cpy.end());
sort(s2cpy.begin(), s2cpy.end());
if(s1cpy != s2cpy) return false;
for(int i=1; i<N; i++){
if(isScramble(s1.substr(0,i), s2.substr(0,i)) && isScramble(s1.substr(i), s2.substr(i)))
return true;
if(isScramble(s1.substr(0,i), s2.substr(N-i)) && isScramble(s1.substr(i), s2.substr(0, N-i)))
return true;
}
return false;
}
};