LeetCode87. 扰乱字符串
判断S2是否是S1的扰乱字符串。根据题目的定义,S1如果经过若干次对于部分子串的翻转操作能够得到S2,则S2是S1的扰乱字符串。
首先,如果S2是S1的扰乱字符串,那么S1中每个字符的出现次数必然和S2中每个字符的出现次数一致,也就是说,我们用两个字符串S3、S4备份一下S1和S2,
对S3和S4排序之后,S3和S4必然是相等的情况下S2才有可能是S1的扰乱字符串,否则返回false。
然后就是要判断S2是否能经过S1的若干次操作得到了。这里就是要枚举S1所有可能得到的扰乱字符串,判断是否有和S2相等的。
可以考虑将S1分割成两个部分,左半部分和右半部分,递归判断左右两半是否分别都可以和S2的左右两半部分相互转换得到。
枚举S1的左半部分的长度(从1到n-1, n是S1的长度),假设当前枚举到了左半部分长度i,递归判断两种可能:
- S1不翻转,则递归判断S1的前i个字符和S2的前i个字符以及S1的后n-i个字符和S2的后n-i个字符是否都可以相互转化得到(递归,依然是通过isScramble()函数判断);
- S1翻转,则递归判断S1的前n-i个字符和S2的后n-i个字符以及S1的后i个字符和S2的前i个字符是否都可以相互转化得到(也是递归判断)。
只要某个解满足,就返回false。
否则,搜遍了所有可能的变换,也不能转化为S2,返回false。
class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1 == s2) {
return true;
}
string s3 = s1, s4 = s2;
sort(s3.begin(), s3.end());
sort(s4.begin(), s4.end());
if(s3 != s4) {
return false;
}
int n = s1.size();
for(int i = 1; i <= n - 1; ++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, n - i), s2.substr(i)) && isScramble(s1.substr(n - i), s2.substr(0, i))) {
return true;
}
}
return false;
}
};