CoderJesse  
wangjiexi@CS.PKU
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.

一个字符串可以通过题目描述的变换成为另一个字符串,有三种可能:
1.这两个字符串本来就是相等的。
2.将这个字符串分为两个字符串,这两个新的字符串都通过题目描述的变换之后可以使得前面的两个字符串相等。
3.将这个字符串分为两个字符串,这两个新的字符串通过题目描述的变换再交换一下位置,可以使得前面的两个字符串相等。

递归实现。(属于深度优先搜索吧)
但光是这样还是会超时。可以试着剪枝。抛去那些本来就没有可能通过变换实现相等的搜索空间,比如两个字符串对应的字母中种类和数量都不相等。

 1 class Solution {
 2 public:
 3     bool isScramble(string s1, string s2) {
 4         // Start typing your C/C++ solution below
 5         // DO NOT write int main() function
 6         return isValid(0,s1.size()-1,0,s2.size()-1,s1,s2);
 7     }
 8     bool isValid(int l1,int r1,int l2,int r2,string &s1,string &s2)
 9     {
10         if(r1 - l1 != r2 - l2)
11             return false;
12         int key = 1;
13         int mark1[26];
14         int mark2[26];
15         memset(mark1,0,sizeof(mark1));
16         memset(mark2,0,sizeof(mark2));
17         for(int i = 0; i <= r1 - l1;i++)
18         {
19             mark1[s1[l1 + i] - 'a']++;
20             mark2[s2[l2 + i] - 'a']++;
21             if(s1[l1 + i] != s2[l2 + i])
22                 key = 0;
23         }
24         if(key == 1)
25             return true;
26         if(l1 == r1)
27             return false;
28         for(int i = 0;i < 26;i++)
29         {
30             if(mark1[i] != mark2[i])
31                 return false;
32         }
33         for(int i = 0; i <= r1 - l1 -1;i++)
34         {
35             bool tag1,tag2; 
36             tag1 = isValid(l1,l1 + i,r2 - i,r2,s1,s2);
37             tag2 = isValid(l1+i+1,r1,l2,r2-i-1,s1,s2);
38             if(tag1 && tag2)
39                 return true;
40             tag1 = isValid(l1,l1 + i,l2,l2 + i,s1,s2);
41             tag2 = isValid(l1+i+1,r1,l2+i+1,r2,s1,s2);
42             if(tag1 && tag2)
43                 return true;            
44         }
45         return false;
46     }
47 };

 

posted on 2013-03-01 14:12  CoderJesse  阅读(230)  评论(0)    收藏  举报