package com.interview.leetcode.dp; /** * Created_By: stefanie * Date: 14-11-17 * Time: 上午11:40 * * Game: https://oj.leetcode.com/problems/scramble-string/ * * Solution: * State matchChar[len][i][j]: the substr which length is len start from i in s1 and j in s2 is scramble * Init: for len = 1, matchChar[1][i][j] = true if s1.charAt(i) == s2.charAt(j) * Produce: matchChar[len][i][j] = true when we could find a break point k: * matchChar[k][i][j] and matchChar[len-k][i+k-1][j+k-1] * or matchChar[k][i][j+len-k] and matchChar[len-k][i+k][j] * example s1 -> s11 and s12 and s2 -> s21 and s22 by K * first s11 matches s21 and s12 matches s22 * or s11 matches s22 and s12 matches s12 //be carefully to calculate the substring * since matchChar[*][i][j] depends on matchChar[*][>i][>j] so, scan len from 2 ~ n and i, j from n-len ~ 0 * Result: matchChar[n][0][0] */ public class ScrambleString { public static boolean isScramble(String s1, String s2) { if( s1.length() != s2.length()) return false; if( s1.length() == 0 || s1.equals(s2)) return true; int n = s1.length(); boolean[][][] scramble = new boolean[n + 1][n][n]; for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ if(s1.charAt(i) == s2.charAt(j)) scramble[1][i][j] = true; } } for(int len = 2; len <= n; len++){ for(int i = 0; i <= n - len; i++){ for(int j = 0; j <= n - len; j++){ boolean found = false; for(int left = 1; left < len && !found; left++){ int right = len - left; found = (scramble[left][i][j] && scramble[right][i+left][j+left]) || (scramble[left][i][j+right] && scramble[right][i+left][j]); } scramble[len][i][j] = found; } } } return scramble[n][0][0]; } }