2015年6月17日星期三

Scramble String leetcode

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.
state:dp[i][j][len] 
这道题我们维护一个三维动态规划量dp[i][j][len] 其中i为s1的起始位置, j为s2的起始位置, len为长度
dp[i][j][len]表示s1从i位到i+ len位置 与 s2从j位到j+len位是否是Scramble String 
初始化:dp[i][j][1] = s1.charAt(i) == s2.charAt(j) 如果s1的i位与s2的j位字母相同 则为true
function: dp[i][j][len] = dp[i][j][l] && dp[i + l][j + l][len - l] || dp[i][j + len - l][l] && dp[i + l] [j][len - l] 
有两种情况为true:
1. 存在着一点k (0 < k < len)使得s1.substring(i, i+k) 和 s2.substring(j, j+k) 为Scramble String  s1.substing(i + k, i +len), s2.substring(j +k, j + len)为Scramble String 就是说s1左边的substring和s2左边的substirng s1右边的substring 和s2右边的substring  为Scramble String  
2. 存在着一点k (0 < k < len)使得s1.substring(i, i+k) 和 s2.substring(j +len - k, j + len)  为Scramble String  s1.substing(i+k, i +len), s2.substring(j, j + len - k)为Scramble String 就是说s1左边的substring和s2右边的substirng s1右边的substring 和s2左边的substring  为Scramble String 
return: dp[0][0][n]
时间O(n^4) 空间 O(n^3)

public class Solution {
    public boolean isScramble(String s1, String s2) {
        if (s1 == null || s2 == null || s1.length() != s2.length()) {
            return false;
        }
        if (s1.equals(s2)) {
            return true;
        }
        int n = s1.length();
        boolean[][][] dp = new boolean[n][n][n + 1];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                dp[i][j][1] = s1.charAt(i) == s2.charAt(j);
            }
        }
        for (int i = n - 1; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                for (int len = 1; len <= n - Math.max(i, j); len++) {
                    for (int l = 1; l < len; l++) {
                        if (dp[i][j][l] && dp[i + l][j + l][len - l] || dp[i][j + len - l][l] && dp[i + l] [j][len - l]) {
                            dp[i][j][len] = true;
                            break;
                        }
                    }
                    // }
                }
            }
        }
        return dp[0][0][n];
    }
}

没有评论:

发表评论