Scramble String
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.
题目:判断s1和s2是否可以通过上述这种旋转得到。分析:注意一开始理解错了题目,以为字符串只能从中间分成两部分,要分各种情况,如great (0,5),长度按(1,4)成g和reat, (2,3)分等。
方法一:暴力,对于字符串s1和s2,按照各种长度,分成两部分,依次判断。注意要前后都判断。 然后递归求解。
代码:
class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1.compare(s2)==0) return true;//递归结束条件
int len1=s1.length();
int len2=s2.length();
if(len1!=len2) return false;
if(len1==1 && s1!=s2) return false;
string sorts1=s1,sorts2=s2;
sort(sorts1.begin(), sorts1.end());//这里sort,对于字母不同的,肯定不能通过旋转得到
sort(sorts2.begin(),sorts2.end());
if(sorts1 != sorts2) return false;
int i;
for(i=1;i<len1;i++){
string s11=s1.substr(0,i);
string s12=s1.substr(i);
string s21=s2.substr(0,i);
string s22=s2.substr(i);
//只要有一部分可以得到,即返回true
if( isScramble(s11,s21)&&isScramble(s12,s22)) return true;
string segs21=s2.substr(0,len1-i);
string segs22=s2.substr(len1-i);
//s1的前半部分和s2的后半部分交换过
if( isScramble(s11,segs22)&&isScramble(s12,segs21)) return true;
}
return false;
}
};
方法二:dp,三维dp。
http://www.cnblogs.com/TenosDoIt/p/3452004.html
对我来说,dp始终是死穴。dp[k][i][j] 表示,s2中从j开始长度为k的串是由s1中从i开始长度为k的串scramble来的。如果是就是ture,否则是false。
那么:dp[1][i][j]= s1[i]==s2[j]? true:false ; 长度为1,如果两个字符相等,就是可旋转到的。
dp[k][i][j]=(dp[div][i][j]&&dp[k-div][i+div][j+div]) || (dp[div][i][k+j-div]&& div[k-div][i+div][j]) 前边表示great rgeat,gr和rg,eat与eat比较。后边表示gr与at,eat与rge比较。
代码:
class Solution {
public:
bool isScramble(string s1, string s2) {
if(s1.size() != s2.size()) return false;
int len=s1.size();
bool dp[len+1][len][len];
//初始化
int i,j;
for(i=0;i<len;i++){
for(j=0;j<len;j++){
dp[1][i][j]= s1[i]==s2[j]? true:false;
}
}
int k;
for(k=2;k<=len;k++){
for(i=0;i<=len-k;i++){
for(j=0;j<=len-k;j++){
dp[k][i][j]=false;//初始化为false
int divlen;
for(divlen=1;divlen<k &&] !dp[k[i][j];divlen++){//<strong>!dp[k][i][j]只要有一个是scramble即可</strong>
dp[k][i][j]=(dp[divlen][i][j] && dp[k-divlen][i+divlen][j+divlen])||
(dp[divlen][i][j+k-divlen] && dp[k-divlen][i+divlen][j]);
}//for divlen
}//for j
}//for i
}//for k
return dp[len][0][0];//s1从0长度为len的串 与 s2从0开始长度为len的串是否是scramble的
}
};