zoukankan      html  css  js  c++  java
  • leetcode87. Scramble String

    leetcode87. Scramble String

    题意:

    给定一个字符串s1,我们可以通过将它分解为两个非空子字符串来表示为二叉树。

    思路:

    递归解法

    对于每对s1,s2. 在s1某处切一刀,s1分成left,right,然后在s2首部开始等长的地方切一刀,切成left,right.只要s1的left和s2的left,s1的right和s2的right同样也构成scramble string就可以了。 递归解法需要剪枝。

    • 剪枝1:s1,s2不等长return
    • 剪枝2:s1,s2字符不相同return

    动态规划

    这题动态规划解法时间不如递归的,但是这题用动态规划还是比较牛皮的。map[i][j][k]三维数组储存,i,j分别表示s1,s2开始的下标,k表示i,j开始后组成的长度。虽然说看到两个字符串比较感觉像动态规划。但是不好想呀。
    参考博文

    ac代码:

    C++ (递归)

    class Solution {
    public:
        bool isScramble(string s1, string s2) {
            
            int len1 = s1.length();
            int len2 = s2.length();
            if(len1 != len2) return false;
            if(len1 == 1) return s1[0] == s2[0]; 
            int cnt[256] = {0};
            for(int i = 0; i < len1; i++) cnt[s1[i]]++;
            for(int j = 0; j < len2; j++) cnt[s2[j]]--;
            for(int i = 0; i < 256; i++)
                if(cnt[i]) return false;
                    
            for(int i = 0; i < len1 - 1; i++)
            {
                if(isScramble(s1.substr(0,i + 1),s2.substr(0,i + 1)) && isScramble(s1.substr(i + 1),s2.substr(i + 1)) ||
                   isScramble(s1.substr(0,i + 1),s2.substr(len2 - 1 - i, i + 1)) && isScramble(s1.substr(i + 1),s2.substr(0,len2 - 1 - i)))
                    return true;
            }
            return false;
        }
    };
    

    C++ (动态规划)

    class Solution {
    public:
        bool isScramble(string s1, string s2) {
            int len1 = s1.length();
            int len2 = s2.length();
            if(len1 != len2) return false;
            if(!len1) return true;
            vector<vector<vector<bool> > >map(len1, vector<vector<bool> >(len1, vector<bool>(len1, false)));
            
            for(int j = 0; j < len1; j++)
                for(int k = 0; k < len1; k++)
                    if(s1[j] == s2[k]) map[0][j][k] = true;
            
            for(int i = 1; i < len1; i++)
            {
                for(int j = len1 - 1; j >= 0; j--)
                {
                    for(int k = len1 - 1; k >= 0; k--)
                    {                    
                        if(k + i + 1 > len1 || j + i + 1 > len1) continue;
                        //map[i][j][k] = false;
                        for(int u = 0; u < i; u++)
                        {
                            if((map[u][j][k + i - u] && map[i - u - 1][j + u + 1][k]) ||
                               (map[u][j][k] && map[i - u - 1][j + u + 1][k + u + 1]))
                            {
                                map[i][j][k] = true;
                                break;
                            }
                        }
                    }
                }
            }
            return map[len1 - 1][0][0];
        }
    };
    
  • 相关阅读:
    leetcode Simplify Path
    leetcode Evaluate Reverse Polish Notation
    leetcode Swap Nodes in Pairs
    leetcode MinStack
    leetcode length of the last word
    empty能否代替isset?
    thinkphp框架的路径
    PHP 反射类的简单使用!
    在windows下配置redis扩展
    phpmyadmin的windows下和linux下的安装。
  • 原文地址:https://www.cnblogs.com/weedboy/p/7214711.html
Copyright © 2011-2022 走看看