87. 扰乱字符串

class Solution {
   public:
    bool isScramble(string s1, string s2) {
        if(s1.length()!=s2.length()) return false;
        //只要寻找到左边字符集合完整包含右边字符集合,就符合
        
        map<char,int> s1Index,s2Index;
        int uniq1Numbers=0,uniq2Numbers = 0;
        //验证两个字符串集合是否完全一致
        for (int i = 0; i < s1.size(); i++)
        {
            if(s1Index.find(s1[i]) != s1Index.end()){
                s1Index[s1[i]]++;
            }else{
                uniq1Numbers++;
                s1Index[s1[i]] = 1;
            }
            
        }
        for (int i = 0; i < s2.size(); i++)
        {
            if(s2Index.find(s2[i])!=s2Index.end()){
                s2Index[s2[i]]++;
            }else{
                uniq2Numbers++;
                s2Index[s2[i]] = 1;
            }
        }
        if(!isSetEqual(s1Index,s2Index)){
            return false;
        }

        return isScramble(s1,s2,0,s1.size(),0,s2.size());
    }

    bool isScramble(string s1, string s2,int start,int end,int star2,int end2) {
        //s1和s2的字符串集合完全一致,序号下标可能不一致.正向或反向都可以试试
        //小于等于3(2)个的时候是符合的.
        if(end <= start + 3){
            return true;
        }
        //printf("compare : %d,%d,%d,%d \r\n",start,end,star2,end2);
        
        map<char,int> s1Index,s2Index,reverseS2Index;
        int uniq1Numbers=0,uniq2Numbers = 0,reverseUniqNumbers = 0;
        int size = end - start;
        for (int i = 0; i < size; i++)
        {
            if(s1Index.find(s1[i+start]) != s1Index.end()){
                s1Index[s1[i+start]]++;
            }else{
                uniq1Numbers++;
                s1Index[s1[i+start]] = 1;
            }
            if(s2Index.find(s2[i+star2])!=s2Index.end()){
                s2Index[s2[i+star2]]++;
            }else{
                uniq2Numbers++;
                s2Index[s2[i+star2]] = 1;
            }
            if(reverseS2Index.find(s2[end2-i-1])!=reverseS2Index.end()){
                reverseS2Index[s2[end2-i-1]]++;
            }else{
                reverseUniqNumbers++;
                reverseS2Index[s2[end2-i-1]] = 1;
            }
            if(i==size-1){
                return false;
            }
            if( uniq2Numbers==uniq1Numbers
            ){
                if(isSetEqual(s1Index,s2Index)){
                    
                    if(isScramble(s1,s2,start,i+1+start,star2,i+1+star2) && isScramble(s1,s2,i+1+start,end,i+1+star2,end2)){
                        return true;
                    }
                }
            }
            if( uniq2Numbers==reverseUniqNumbers
            ){
                if(isSetEqual(s1Index,reverseS2Index)){
                    
                    if(isScramble(s1,s2,start,i+1+start,end2-i-1,end2) && isScramble(s1,s2,i+1+start,end,star2,end2-1-i)){
                        return true;
                    }
                }
            }

        }

      
         
        return false;
        
    }

    bool isSetEqual(map<char,int> m1,map<char,int> m2){
        // Solution sol;
        // sol.printMaps(m1);
        // sol.printMaps(m2);
        if(m1.size()!=m2.size()){
            return false;
        }
        map<char,int>::iterator it1 = m1.begin();
        while(it1!=m1.end()){
            if(m2.find(it1->first)==m2.end() 
            || it1->second!=m2[it1->first]){
                return false;
            }
            it1++;
        }
        return true;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值