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,递归判断两种可能:

  1. S1不翻转,则递归判断S1的前i个字符和S2的前i个字符以及S1的后n-i个字符和S2的后n-i个字符是否都可以相互转化得到(递归,依然是通过isScramble()函数判断);
  2. 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;
    }
};
posted @ 2020-07-17 22:57  machine_gun_lin  阅读(143)  评论(0编辑  收藏  举报