Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. (Hard)
For example,
Given:
s1 = "aabcc"
,
s2 = "dbbca"
,
When s3 = "aadbbcbcac"
, return true.
When s3 = "aadbbbaccc"
, return false.
分析:
开始的思路是DFS搜索,当然结果也是华丽地超时了。
然后考虑动态规划。开始定义状态上出现了一些问题,甚至想到三维数组。
但是仔细考虑一下,采用双序列动态规划问题常见的状态定义,dp[i][j]表示s1的前 i 个字符和s2的前 j 个字符能否搭配组成s3(自然就是前i + j 位)。
然后就是递推关系式根据s1[i - 1] 与 s2[j - 1]与 s3[i + j - 1]是否相等(具体见代码)
注意:
s1,s2的长度加起来不等于s3的长度,直接返回false
初始化的时候发现二维数组直接用{false}并不能全部初始化,这里WA了一次
代码:
1 class Solution { 2 public: 3 bool isInterleave(string s1, string s2, string s3) { 4 if (s1.size() + s2.size() != s3.size()) { //长度不一致判断 5 return false; 6 } 7 bool dp[s1.size() + 1][s2.size() + 1]; //初始化不能做到一次初始化问false 8 9 dp[0][0] = true; 10 11 for (int i = 1; i <= s1.size(); ++i) { 12 if (s1[i - 1] == s3[i - 1] && dp[i - 1][0]) { 13 dp[i][0] = true; 14 } 15 else { 16 dp[i][0] = false;; 17 } 18 } 19 for (int i = 1; i <= s2.size(); ++i) { 20 if (s2[i - 1] == s3[i - 1] && dp[0][i - 1]) { 21 dp[0][i] = true; 22 } 23 else { 24 dp[0][i] = false; 25 } 26 } 27 for (int i = 1; i <= s1.size(); ++i) { 28 for (int j = 1; j <= s2.size(); ++j) { 29 dp[i][j] = false; 30 if (s1[i - 1] == s3[i + j - 1] && s2[j - 1] && s3[i + j - 1]) { 31 dp[i][j] = (dp[i - 1][j] || dp[i][j - 1]); 32 } 33 else if (s1[i - 1] == s3[i + j - 1]) { 34 dp[i][j] = dp[i - 1][j]; 35 } 36 else if (s2[j - 1] == s3[i + j - 1]) { 37 dp[i][j] = dp[i][j - 1]; 38 } 39 } 40 } 41 return dp[s1.size()][s2.size()]; 42 } 43 };