题目分析:
- 给定字符串s1,s2,s3,判断s3是否可能由s1和s2交错组合而成。交错指前后顺序不变的交叉
解题思路:
递归求解
一个一个字符的判断,判断过程中利用递归实现。时间复杂度为O(2^(m+n));
动态规划
定义状态dp[i+1][j+1]:表示s1[0,…,i]与s2[0,…,j]能够交替形成s3[0,…,i+j+1]部分。
状态转移方程为:dp[i+1][j+1] = (dp[i][j+1] && s1[i] == s3[i+j+1] | (dp[i+1][j] && s2[j] == s3[i+j+1]);
实现程序
class Solution { public: //递归实现(超时) bool isInterleave1(string s1, string s2, string s3) { if (s3.length() != s1.length() + s2.length()) return false; if (s1.length() == 0) return s2 == s3; if (s2.length() == 0) return s1 == s3; bool sub1 = false; bool sub2 = false; // 判断字符是否相等,并对后面的字符进行递归处理 if (s1[0] == s3[0]) sub1 = isInterleave1(s1.substr(1), s2, s3.substr(1)); // 判断字符是否相等,并对后面的字符进行递归处理 if (s2[0] == s3[0]) sub2 = isInterleave1(s1, s2.substr(1), s3.substr(1)); return sub1 || sub2; } //动态规划实现 bool isInterleave(string s1, string s2, string s3) { int m = s1.length(); int n = s2.length(); // 判断长度是否符合条件 if (m + n != s3.length()) return false; bool dp[m + 1][n + 1]; dp[0][0] = true; // 初始化边界 for (int i = 0; i < n; i++) dp[0][i + 1] = dp[0][i] && s2[i] == s3[i]; for (int i = 0; i < m; i++) dp[i + 1][0] = dp[i][0] && s1[i] == s3[i]; // 递归进行求解 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { dp[i + 1][j + 1] = (dp[i][j + 1] && s1[i] == s3[i + j + 1]) | (dp[i + 1][j] && s2[j] == s3[i + j + 1]); } } // 返回最终结果 return dp[m][n]; } };