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.
个人觉得这道题真是挺难的,做了两个晚上,最后看了别人的解法,思路在注释里:
class Solution { public: /************************************************************************* ** 思路:1)最初想到的是如果两个字符串能够通过题目给出的交换方式的到, ** 那么对两个字符串进行排序,如果排序结果相同,则证明两个字符串 ** 就满足要求返回true,结果提交,果断贡献WA,原因是排序相等只是 ** scramble 的必要非充分条件 ** 2)递归思路,字符串s1和s2是scramble的充分必要条件是: ** s1.compare(s2)=0 or ** ( s1.substr(0,i)和s2.substr(0,i)是scramble and s1.substr(i+1,len-i)和s2.substr(i+1,len-i)是scramble) or ** (s1.substr(0,i)和s2.substr(len-i+1,i)是scramble and s1.substr(i+1,len-i)和s2.substr(0,len-i)是scramble ) ** 由此对于两个字符串s1和s2存在len-1中分割选择,但是递归到下层时会存在大量重复计算 ** 3) 为了避免重复计算,使用动态规划,按照2)中描述的递归式,申 ** 请三维dp数组dp[len][len][len],第一维表示字符串s1的起点,第二维表 ** 示s2的起点,第三维表示字串的长度,最终结果表示为dp[0][0][len] *************************************************************************/ bool isScramble(string s1, string s2) { int len=s1.size(); if (len==0){ return true; } vector <vector <vector <bool>>> dp(len,vector<vector<bool>>(len,vector<bool>(len,false))); //initialization dp for(int i=0;i<len;i++){ for(int j=0;j<len;j++){ if(s1[i]==s2[j]){ dp[i][j][0]=true; } } } //dp for(int l=2;l<=len;l++){ for(int i=0;i+l<=len;i++){ for(int j=0;j+l<=len;j++){ // k partations for (int k=1;k<l;k++){ if ((dp[i][j][k-1]&&dp[i+k][j+k][l-k-1])|| dp[i][j+k][l-k-1]&&dp[i+l-k][j][k-1]){ dp[i][j][l-1]=true; break; } } } } } return dp[0][0][len-1]; } };