题目 <https://leetcode-cn.com/problems/scramble-string/>
一开始看是动态规划,还想着dp[i][j]表示s1[i ~ j]能否通过转换变成s2[i~j],我还是太年轻了。。。
之后是变成判断,i ~ j之间,是否存在k,使得i ~ k ,k+1 ~ j,s1和s2对应区域的字符数相等,差了点意思,不过很接近了(也就是卡在了最后几个样例)
最终思路,仔细思考了题意,其实存在交换和不交换两种,那其实就有两种情况
情况一:i ~ j之间,是否存在k,使得s1[i ~ k]和s2[i ~ k] ,s1[k+1 ~ j]和s2[k+1 ~ j],对应区域的字符数相等(头和头,意思是没发生交换)
情况一:i ~ j之间,是否存在k,使得s1[i ~ k]和s2[j+i-k ~ j] ,s1[k+1 ~ j]和s2[i ~ j+i-k-1],对应区域的字符数相等(头和尾,意思是发生交换)
之后再递归下去
怎么判断k呢,看我程序
bool isScramble_n(char * s1, char * s2,int s_len){
if(s_len == 0){
return true;
}
if(memcmp(s1,s2,s_len) == 0){
return true;
}
int tmp[128];
int i,same = 0;
memset(tmp,0,sizeof(tmp));
same=0;
for(i=0;i<s_len-1;i++){//两种选择之一:没有发生交换
tmp[s1[i]]++;
if(tmp[s1[i]] <= 0){
same--;
}else{
same++;
}
tmp[s2[i]]--;
if(tmp[s2[i]] >= 0){
same--;
}else{
same++;
}
if(same == 0){
if(isScramble_n(s1,s2,i+1) && isScramble_n(s1+i+1,s2+i+1,s_len-i-1)){
return true;
}
}
}
memset(tmp,0,sizeof(tmp));
same=0;
for(i=0;i<s_len-1;i++){//两种选择之二:发生交换
tmp[s1[i]]++;
if(tmp[s1[i]] <= 0){
same--;
}else{
same++;
}
tmp[s2[s_len-i-1]]--;
if(tmp[s2[s_len-i-1]] >= 0){
same--;
}else{
same++;
}
if(same == 0){
if(isScramble_n(s1,s2+s_len-i-1,i+1) && isScramble_n(s1+i+1,s2,s_len-i-1)){
return true;
}
}
}
return false;
}
bool isScramble(char * s1, char * s2){
int s_len = strlen(s1);
return isScramble_n(s1,s2,s_len);
}