zoukankan      html  css  js  c++  java
  • [LeetCode] Scramble String 字符串 dp

    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.

    Hide Tags
     Dynamic Programming String
     
        题目开始想还是挺复杂的,第一想法便是二叉树搜索,把全部可能的结果搜出来,然后如果找到了便是,找不到便不是,这样写的话速度需要考虑,提高的方法是深度查找时候判断输入的参数中字符种类个数是否一样:
    class Solution {
    public:
        bool isScramble(string s1, string s2) {
            int len1 = s1.size(),len2 = s2.size();
            if(help_f(s1,s2)){
                if(s1==s2)  return true;
                for( int i =1;i<len1;i++){
                    if(s1.substr(0,i)+s1.substr(i)==s2)    return true;
                }
                for( int i=1;i<len1;i++){
                    if(isScramble(s1.substr(0,i),s2.substr(0,i))&&isScramble(s1.substr(i),s2.substr(i)))
                        return true;
        //            cout<<s1.substr(0,i)<<" "<<s2.substr(len2-i)<<" "<<s1.substr(len1-i)<<" "<<s2.substr(0,i)<<endl;
                    if(isScramble(s1.substr(0,i),s2.substr(len2-i))&&isScramble(s1.substr(i),s2.substr(0,len2-i)))
                        return true;
                }
            }
            return false;
        }
        bool help_f(string &s1,string &s2)
        {
            if(s1.size()!=s2.size())    return false;
            int c[26]={0};
            for(int i=0;i<s1.size();i++)    c[s1[i]-'a'] ++;
            for(int i=0;i<s2.size();i++){
                c[s2[i]-'a']--;
                if(c[s2[i]-'a']<0)  return false;
            }
            return true;
        }
    };
      第二想法便是动态规划了,设table[i][j][len],i j 为字符串s1 s2 的起始位置,len 为需要考虑的长度,如果s1 的i to i + len  与 s2 的 j to j+len 符合,便为true,在长度范围内,遍历每个断开的位置,有:
     
    tab[i][j][len]  |=   tab[i][j][l] && tab[i+l][j+l][len-l]   or    tab[i][j][len]   |=  tab[i][j+len-l][l] && tab[i+l][j][len-l]
     
    class Solution
    {
    public:
        bool isScramble(string s1, string s2)
        {
            int len1=s1.size(),len2=s2.size();
            if(len1!=len2)  return false;
            bool table[100][100][100]={false};
            for(int i=len1-1;i>=0;i--){
                for(int j=len1-1;j>=0;j--){
                    table[i][j][1]=(s1[i]==s2[j]);
                    for(int tmpLen=2;i+tmpLen<=len1&&j+tmpLen<=len1;tmpLen++){
                        for(int idx=1;idx<tmpLen;idx++){
                            table[i][j][tmpLen]|=table[i][j][idx]&&table[i+idx][j+idx][tmpLen-idx];
                            table[i][j][tmpLen]|=table[i][j+tmpLen-idx][idx]&&table[i+idx][j][tmpLen-idx];
                        }
                    }
                }
            }
            return table[0][0][len1];
        }
    };
     
  • 相关阅读:
    uboot 环境变量
    U-boot的环境变量: bootcmd 和bootargs
    linux中的rootfs/initrd/ramfs/initramfs
    关于Linux启动时挂载rootfs的几种方式
    u-boot-2011.06在基于s3c2440开发板的移植之引导内核与加载根文件系统
    MySQL列出当前月的每一天
    SQL 标量函数-----日期函数 day() 、month()、year()
    mysql 中 DATE_ADD函数和 DATE_SUB函数用法
    mysql 中 DATE_ADD(date,INTERVAL expr type)
    mysql中date_add()函数的使用?
  • 原文地址:https://www.cnblogs.com/Azhu/p/4239980.html
Copyright © 2011-2022 走看看