• [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];
        }
    };
     
  • 相关阅读:
    BW中变量增强学习
    视频压制参数设置详细说明(转)
    swf文件格式解析(二)
    关于FP10.2的自定义鼠标功能
    swf文件格式解析(一)
    如何判断winform程序已安装过
    flashbuilder4.5 作为eclipse插件
    安装程序无法创建新的系统分区,也无法定位现有系统分区 (转载于百度文库)
    【转】VS2008建造打包法度将安装路径写入注册表
    【高清视频压制教程】使用MeGUI压制视频教程(以PSP视频为例)(转载)
  • 原文地址:https://www.cnblogs.com/Azhu/p/4239980.html
Copyright © 2020-2023  润新知