87. 扰乱字符串 Scramble String

题目 <https://leetcode-cn.com/problems/scramble-string/>

一开始看是动态规划,还想着dp[i][j]表示s1[i ~ j]能否通过转换变成s2[i~j],我还是太年轻了。。。

之后是变成判断,i ~ j之间,是否存在k,使得i ~ k ,k+1 ~ j,s1和s2对应区域的字符数相等,差了点意思,不过很接近了(也就是卡在了最后几个样例)

最终思路,仔细思考了题意,其实存在交换和不交换两种,那其实就有两种情况

情况一:i ~ j之间,是否存在k,使得s1[i ~ k]和s2[i ~ k] ,s1[k+1 ~ j]和s2[k+1 ~ j],对应区域的字符数相等(头和头,意思是没发生交换)

情况一:i ~ j之间,是否存在k,使得s1[i ~ k]和s2[j+i-k ~ j] ,s1[k+1 ~ j]和s2[i ~ j+i-k-1],对应区域的字符数相等(头和尾,意思是发生交换)

之后再递归下去

怎么判断k呢,看我程序

bool isScramble_n(char * s1, char * s2,int s_len){
    if(s_len == 0){
        return true;
    }

    if(memcmp(s1,s2,s_len) == 0){
        return true;
    }

    int tmp[128];
    int i,same = 0;

    memset(tmp,0,sizeof(tmp));
    same=0;
    for(i=0;i<s_len-1;i++){//两种选择之一:没有发生交换
        tmp[s1[i]]++;
        if(tmp[s1[i]] <= 0){
            same--;
        }else{
            same++;
        }

        tmp[s2[i]]--;
        if(tmp[s2[i]] >= 0){
            same--;
        }else{
            same++;
        }

        if(same == 0){
            if(isScramble_n(s1,s2,i+1) && isScramble_n(s1+i+1,s2+i+1,s_len-i-1)){
                return true;
            }
        }
    }

    memset(tmp,0,sizeof(tmp));
    same=0;
    for(i=0;i<s_len-1;i++){//两种选择之二:发生交换
        tmp[s1[i]]++;
        if(tmp[s1[i]] <= 0){
            same--;
        }else{
            same++;
        }

        tmp[s2[s_len-i-1]]--;
        if(tmp[s2[s_len-i-1]] >= 0){
            same--;
        }else{
            same++;
        }

        if(same == 0){
            if(isScramble_n(s1,s2+s_len-i-1,i+1) && isScramble_n(s1+i+1,s2,s_len-i-1)){
                return true;
            }
        }
    }

    return false;
}

bool isScramble(char * s1, char * s2){
    int s_len = strlen(s1);
    return isScramble_n(s1,s2,s_len);
}

猜你喜欢

转载自blog.csdn.net/ZRXSLYG/article/details/111773737
今日推荐