Scramble String

Scramble String

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":

    great
   /    \
  gr    eat
 / \    /  \
g   r  e   at
           / \
          a   t

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".

    rgeat
   /    \
  rg    eat
 / \    /  \
r   g  e   at
           / \
          a   t

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".

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a

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.

题目:判断s1和s2是否可以通过上述这种旋转得到。

分析:注意一开始理解错了题目,以为字符串只能从中间分成两部分,要分各种情况,如great (0,5),长度按(1,4)成g和reat, (2,3)分等。

方法一:暴力,对于字符串s1和s2,按照各种长度,分成两部分,依次判断。注意要前后都判断。 然后递归求解。

代码:

class Solution {
public:
    bool isScramble(string s1, string s2) {
        if(s1.compare(s2)==0) return true;//递归结束条件
        int len1=s1.length();
        int len2=s2.length();
        if(len1!=len2) return false;
        if(len1==1 && s1!=s2) return false;
        string sorts1=s1,sorts2=s2;
        sort(sorts1.begin(), sorts1.end());//这里sort,对于字母不同的,肯定不能通过旋转得到
        sort(sorts2.begin(),sorts2.end());
        if(sorts1 != sorts2) return false;
        
        int i;
        for(i=1;i<len1;i++){
            string s11=s1.substr(0,i);
            string s12=s1.substr(i);
            
            string s21=s2.substr(0,i);
            string s22=s2.substr(i);
            //只要有一部分可以得到,即返回true
            if( isScramble(s11,s21)&&isScramble(s12,s22)) return true;
            
            string segs21=s2.substr(0,len1-i);
            string segs22=s2.substr(len1-i);
            //s1的前半部分和s2的后半部分交换过
            if( isScramble(s11,segs22)&&isScramble(s12,segs21)) return true;
            
        }
        return false;
    }
};

方法二:dp,三维dp。

http://www.cnblogs.com/TenosDoIt/p/3452004.html

对我来说,dp始终是死穴。dp[k][i][j] 表示,s2中从j开始长度为k的串是由s1中从i开始长度为k的串scramble来的。如果是就是ture,否则是false。

那么:dp[1][i][j]= s1[i]==s2[j]? true:false ; 长度为1,如果两个字符相等,就是可旋转到的。

dp[k][i][j]=(dp[div][i][j]&&dp[k-div][i+div][j+div]) || (dp[div][i][k+j-div]&& div[k-div][i+div][j]) 前边表示great rgeat,gr和rg,eat与eat比较。后边表示gr与at,eat与rge比较。

代码:

class Solution {
public:
    bool isScramble(string s1, string s2) {
        if(s1.size() != s2.size()) return false;
        int len=s1.size();
        
        bool dp[len+1][len][len];
        //初始化
        int i,j;
        for(i=0;i<len;i++){
            for(j=0;j<len;j++){
                dp[1][i][j]= s1[i]==s2[j]? true:false;
            }
        }
        int k;
        for(k=2;k<=len;k++){
            for(i=0;i<=len-k;i++){
                for(j=0;j<=len-k;j++){
                    dp[k][i][j]=false;//初始化为false
                    
                    int divlen;
                    for(divlen=1;divlen<k &&] !dp[k[i][j];divlen++){//<strong>!dp[k][i][j]只要有一个是scramble即可</strong>
                        dp[k][i][j]=(dp[divlen][i][j] && dp[k-divlen][i+divlen][j+divlen])||
                        (dp[divlen][i][j+k-divlen] && dp[k-divlen][i+divlen][j]);
                    }//for divlen
                    
                }//for j
            }//for i
        }//for k
        return dp[len][0][0];//s1从0长度为len的串 与 s2从0开始长度为len的串是否是scramble的
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值