• [Leetcode] 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.

    题意:判断s2是否是s1的爬行字符串。

    思路:如果s1和s2是scramble,那么必然存在一个在s1上的长度len1,将s1分成s11和s12两段同样有,s21和s22,那么要么s11和s21是scramble的并且s12和s22是scramble的;要么s11和s22是scramble的并且s12和s21是scramble的。如: rgeat 和 great 来说,rgeat 可分成 rg 和 eat 两段, great 可分成 gr 和 eat 两段,rg 和 gr 是scrambled的, eat 和 eat 当然是scrambled。参考了GrandyangEason Liu的博客。

    代码如下:

     1 class Solution {
     2 public:
     3     bool isScramble(string s1, string s2) 
     4     {
     5         if(s1.size() !=s2.size())   return false;
     6         if(s1==s2)  return true;
     7 
     8         string str1=s1,str2=s2;
     9         sort(str1.begin(),str1.end());
    10         sort(str2.begin(),str2.end());
    11         if(str1 !=str2) return false;
    12 
    13         for(int i=1;i<s1.size();++i)
    14         {
    15             string s11=s1.substr(0,i);
    16             string s12=s1.substr(i);
    17             string s21=s2.substr(0,i);
    18             string s22=s2.substr(i);
    19 
    20             if(isScramble(s11,s21)&&isScramble(s12,s22))    
    21                 return true;
    22             else
    23             {
    24                 s21=s2.substr(s1.size()-i);
    25                 s22=s2.substr(0,s1.size()-i);
    26                 if(isScramble(s11,s21)&&isScramble(s12,s22))    
    27                     return true;
    28             }
    29 
    30         }    
    31         return false;
    32     }
    33 };

    注:substr()函数的用法:str.substr(start,Length)从某一位置start开始,指定长度为length的子字符串,若,length为0或者为负数返回空串;若,没有指定该参数,则,从指定位置开始直到字符串的最后。

    方法二:动态规划,参见Grandyang的博客,维护量res[i][j][n],其中i是s1的起始字符,j是s2的起始字符,而n是当前的字符串长度,res[i][j][len]表示的是以i和j分别为s1和s2起点的长度为len的字符串是不是互为scramble。看看递推式,也就是怎么根据历史信息来得到res[i][j][len]:当前s1[i...i+len-1]字符串劈一刀分成两部分,然后分两种情况:第一种是左边和s2[j...j+len-1]左边部分是不是scramble,以及右边和s2[j...j+len-1]右边部分是不是scramble;第二种情况是左边和s2[j...j+len-1]右边部分是不是scramble,以及右边和s2[j...j+len-1]左边部分是不是scramble,如果以上两种情况有一种成立,说明s1[i...i+len-1]和s2[j...j+len-1]是scramble的.

    代码如下:

     1 class Solution {
     2 public:
     3     bool isScramble(string s1, string s2) 
     4     { 
     5         if(s1.size() !=s2.size())   return false;
     6         if(s1==s2)  return true;
     7 
     8         int len=s1.size();
     9         vector<vector<vector<bool>>> dp(len,
    10                     vector<vector<bool>>(len,vector<bool>(len+1,false)));
    11         for(int i=0;i<len;++i)
    12         {
    13             for(int j=0;j<len;++j)
    14             {
    15                 dp[i][j][1]=(s1[i]==s2[j]);
    16             }
    17         }
    18 
    19         for(int n=2;n<=len;++n)
    20         {
    21             for(int i=0;i<=len-n;++i)
    22             {
    23                 for(int j=0;j<=len-n;++j)
    24                 {
    25                     for(int k=1;k<n;++k)
    26                     {
    27                         if((dp[i][j][k]&&dp[i+k][j+k][n-k])||
    28                         (dp[i+k][j][n-k]&&dp[i][j+n-k][k]))
    29                         {
    30                             dp[i][j][n]=true;
    31                         }
    32                     }
    33                 }
    34             }
    35         }
    36 
    37         return dp[0][0][len];
    38     }
    39 };
  • 相关阅读:
    SGU 205. Quantization Problem
    BZOJ1009: [HNOI2008]GT考试
    SGU 204. Little Jumper
    Spring Aspect 获取请求参数
    springboot 是用拦截器Interceptor获取请求的控制器和请求的方法名
    spring boot Filter过滤器的简单使用
    Java 使用Query动态拼接SQl
    java 传入list集合 返回树形菜单,for循环遍历
    spring data jpa 的简单使用
    vue项目引入element
  • 原文地址:https://www.cnblogs.com/love-yh/p/7133138.html
Copyright © 2020-2023  润新知