题目描述
给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树。在扰乱这个字符串的过程中,我们可以挑选任何一个非叶节点,然后交换它的两个子节点。给出两个长度相等的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。
题解
动态规划
状态:dp[i][j][len] 表示从字符串 S 中 i 开始长度为 len 的字符串是否能变换为从字符串 T 中 j 开始长度为 len 的字符串。
转移方程:dp[i][j][k]=${OR}_{1<=w<=k-1}${(dp[i][j][w]&&dp[i+w][j+w][k-w])||(dp[i][j+k-w][w]&&dp[i+w][j][k-w])}
初始状态:len<=1时,dp[i][j][1] = (s1[i] == s2[j])
返回结果:d[0][0][len]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| bool isScramble(string s1, string s2) { int len = s1.length(); if (len <= 1)return s1 == s2; bool*** dp; dp = new bool**[len]; for (int i = 0; i < len; i++) dp[i] = new bool*[len]; for (int i = 0; i < len; i++) for (int j = 0; j < len; j++) dp[i][j] = new bool[len+1]; for (int i = 0; i < len; i++) for (int j = 0; j < len; j++) for (int k = 0; k<=len; k++) dp[i][j][k] = false; for (int i = 0; i < len; i++) for (int j = 0; j < len; j++) dp[i][j][1] = (s1[i] == s2[j]); for (int k = 2; k <= len; k++) { for (int i = 0; i <=len-k;i++) { for (int j = 0; j <= len - k; j++) { for (int w = 1; w <= k-1; w++) { if ((dp[i][j][w] && dp[i + w][j + w][k- w]) || (dp[i][j + k - w][w] && dp[i + w][j][k - w])) { dp[i][j][k] = true; break; } } } } } return dp[0][0][len]; }
|
加油呀。菜是原罪啊。