Leetcode--Scramble String

Topic: Hard


Question:

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.

» Solve this problem


Method:

1.Recursive--base case is two strings length is equal or not and whether the only char in these two string are the same. Once the length is bigger than 1, traverse the string which-ever, OK, find out the the substring with length i for two sides and make a letter comparison to see do they have the same letters in the string? If yes, go to next recursion to see whether the two sides of each string still have same substrings at the specific position.

2. DP-- 3 dimensional DP, oh my! But remember to ask this question: what do we remember? In this case, we remember the already compared substrings' situations. To be continued...


Code:

public class Solution {
    public boolean isScramble(String s2, String s1) {
        // Start typing your Java solution below
        // DO NOT write main() function
        if(s1.length() != s2.length()) return false;
        else if(s1.length() == 1) return s1.charAt(0)==s2.charAt(0);
        else{
            for(int i=1; i<s2.length(); i++){
                String a1 = s1.substring(0, i);
                String a2 = s1.substring(i);
                String b1 = s2.substring(0, i);
                String b2 = s2.substring(i);
                
                if(checkLetters(a1, b1)){
                    if(isScramble(a1, b1) && isScramble(a2, b2)){
                        return true;
                    }
                }
                
                b1 = s2.substring(0, a2.length());
                b2 = s2.substring(a2.length());
                if(checkLetters(a1, b2)){
                    if(isScramble(a1, b2) && isScramble(a2, b1)){
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    
    private boolean checkLetters(String s1, String s2){
        int[] set = new int[256];
        for(int i=0; i<s1.length(); i++)
            set[s1.charAt(i)-'0']++;
        
        for(int i=0; i<s2.length(); i++){
            if(set[s2.charAt(i)-'0']-- == 0)
                return false;
        }
        
        return true;
    }
}


Code for DP:

boolean isScramble(String s1, String s2) {
    if(s1.equals(s2))
        return true;
    boolean[][][] scrambled = 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++){
            scrambled[i][j][0] = true; 
            scrambled[i][j][1] = s1.charAt(i) == s2.charAt(j);
        }

    for(int i = s1.length() - 1; i >= 0 ; i--)
        for(int j = s2.length() - 1; j >= 0; j--)
            for(int n = 2; n <= Math.min(s1.length() - i, s2.length() - j); n ++)
                for(int m = 1; m < n; m++){
                    scrambled[i][j][n] |= scrambled[i][j][m] && scrambled[i + m][j + m][n - m] || scrambled[i][j + n - m][m] && scrambled[i + m][j][n - m];
                    if(scrambled[i][j][n])  break;
                }
    return scrambled[0][0][s1.length()]; 
}



Summary:

太难,不正常的一道面试题,DP运用了三维布尔数组存放已经比较过的scramble substring,解法依旧在研究中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值