Skip to content

Latest commit

 

History

History
68 lines (60 loc) · 2.87 KB

dp4-scramble-string.md

File metadata and controls

68 lines (60 loc) · 2.87 KB

题目:

  • 我们将 "rgtae” 称作 "great" 的一个扰乱字符串。给出两个长度相等的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。 思路:
  • 递归:对于任意子串s1,s2来说,如果从第i个字符处切开,s1得到左边s11,右边s12子字符串,s2得到左边s21,s22子字符串,那么一定满足,s11和s21是扰乱字符串并且s12和s22是扰乱字符串 ,或者s11和s22是扰乱字符串并且s12和s21是扰乱字符串。
  • 动态规划:那一个变量来维护不同长度的子字符串的扰乱字符串的结果值,即result[i][j][k],其中i表示s1的起始下标,j表示s2的起始下标,k表示当前字符串长度,判断规则和递归一样,最后的返回为result[0][0][s1.length()]
    // 动态规划代码
   class Solution {
    public:
        bool isScramble(string s1, string s2) {
            if(s1.length()!=s2.length()) return false;
            if(s1.length()==1){
                return s1==s2;
            }
            if(s1.length()==0) {
                return true;
            }
            boolean[][][] res = new boolean[s1.length()][s2.length()][s1.length()+1];
            for(int i=0;i<s1.length();i++){
                for(int j=0;j<s2.length();j++) {
                    res[i][j][1] = s1.charAt(i) == s2.charAt(j);
                }
            }
            for(int len=2;len<=s1.length();len++) {
                // 假设s1.length==5 
                //2->6 原串切割后的子串长度
                for(int i=0;i<s1.length()-len+1;i++) {
                    // 0->5-2...6+1 => 0=>4,3,2,1,0
                    // 子串s11起始点从4=>0
                    for(int j=0;j<s2.length()-len+1;j++) {
                        // 0->5-2...6+1 => 0=>4,3,2,1,0
                        // 子串s21的起始点从4=>0
                        
                        for(int k=1;k<len;k++) {
                            
                            // res[i][j][k] => s11~s21
                            // res[i+k][j+k][len-k] => s12~s22
                            // res[i+k][j][len-k] => s12~s21
                            // res[i][j+len-k][k] => s11~s22
                            res[i][j][len]=res[i][j][k]&&res[i+k][j+k][len-k] || res[i+k][j][len-k]&&res[i][j+len-k][k];
                        }
                    }
                }
            }
            return res[0][0][s1.length()];
        }
    };

循环的解释: 首先按单个字符比较,判断它们之间是否是scrambled的 在更新第二个表中第一个值(gr和rg是否为scrambled的)时,比较了第一个表中的两种构成,一种是 g与r, r与g,另一种是 g与e, r与e,其中前者是真,只要其中一个为真,则将该值赋真。

     r    g    e
g    x    √    x
r    √    x    x
e    x    x    √


     rg    ge
gr    √    x
re    x    x


     rge
gre   √