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.
这道题一开始理解题意的时候出现了偏差。不是从中间partition,是任意位置。
1. 递归:
简单的说,就是s1和s2是scramble的话,那么必然存在一个在s1上的长度l1,将s1分成s11和s12两段,同样有s21和s22。
那么要么s11和s21是scramble的并且s12和s22是scramble的;
要么s11和s22是scramble的并且s12和s21是scramble的。
如果要能通过OJ,还必须把字符串排序后进行剪枝
http://blog.unieagle.net/2012/10/23/leetcode%E9%A2%98%E7%9B%AE%EF%BC%9Ascramble-string%EF%BC%8C%E4%B8%89%E7%BB%B4%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/
3维dp
boolean dp[k][i][j]: s1.substring(i,i+k+1) 和 s2.substring(j,j+k+1)是否scramble.
k相当于offset,所以完成dp矩阵的时候注意 i+k不能超过n-1[code]
public class Solution { public boolean isScramble(String s1, String s2) { if(s1==null && s2==null)return true; if(s1.length()!=s2.length())return false; int n=s1.length(); if(n==0)return true; boolean dp[][][]=new boolean[n][n][n]; for(int k=0;k<n;k++) { for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(k==0)dp[k][i][j]=s1.charAt(i)==s2.charAt(j); else if(i+k<n && j+k<n) { int offset=0; while(offset<k) { if( ( dp[offset][i][j] && dp[k-offset-1][i+offset+1][j+offset+1] ) || ( dp[offset][i][j+k-offset] && dp[k-offset-1][i+offset+1][j] )) { dp[k][i][j]=true; break; } offset++; } } } } } return dp[n-1][0][0]; } }