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.
首先我想到的是scrambled string 就是原来string的全排列,而且似乎是这样的。所以算法如下:
1 public class Solution { 2 public boolean isScramble(String s1, String s2) { 3 // Start typing your Java solution below 4 // DO NOT write main() function 5 if(s1 == null) return false; 6 HashMap<Integer,Integer> s1m = new HashMap<Integer,Integer>(); 7 for(int i = 0; i < s1.length(); i ++){ 8 Integer c = Integer.valueOf(s1.charAt(i)); 9 Integer cc= Integer.valueOf(s2.charAt(i)); 10 if(s1m.containsKey(c)){ 11 s1m.put(c, s1m.get(c) + 1); 12 }else{ 13 s1m.put(c,1); 14 } 15 if(s1m.containsKey(cc)){ 16 s1m.put(cc,s1m.get(cc) - 1); 17 }else{ 18 s1m.put(cc,-1); 19 } 20 } 21 Iterator it= s1m.keySet().iterator(); 22 while (it.hasNext()) 23 { 24 Object key=it.next(); 25 if(s1m.get(key) != 0){ 26 return false; 27 } 28 } 29 return true; 30 } 31 }
但是 测试是发现问题:
input | output | expected | |
---|---|---|---|
"abcd", "bdac" | true | false |
X
|
看出来 并不是全排列,而是有相对顺序的。
然后就想应该可以用DP来做,从顶往下走,一定在某一部能发现 s1 的左子树 等于 s2的右子树, s1的右子树 等于 s2的左子树。
这是使用递归的算法:
1 public class Solution { 2 public boolean isScramble(String s1, String s2) { 3 // Start typing your Java solution below 4 // DO NOT write main() function 5 if(s1.equals(s2)) return true; 6 int v1 = 0; 7 int v2 = 0; 8 int size = s1.length(); 9 for(int i = 0; i < size; i ++){ 10 v1 += Integer.valueOf(s1.charAt(i)); 11 v2 += Integer.valueOf(s2.charAt(i)); 12 } 13 if(v1 != v2) return false; 14 for (int i=1; i<size;i++) { 15 if (isScramble(s1.substring(0,i), s2.substring(0,i)) && isScramble(s1. 16 substring(i), s2.substring(i))) 17 return true; 18 if (isScramble(s1.substring(0,i), s2.substring(size-i)) && isScramble( 19 s1.substring(i), s2.substring(0,size-i))) 20 return true; 21 } 22 return false; 23 } 24 }