[LeetCode] Interleaving String 解题思路
Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.
For example,
Given:
s1 = "aabcc"
,
s2 = "dbbca"
,
When s3 = "aadbbcbcac"
, return true.
When s3 = "aadbbbaccc"
, return false.
问题 : 给定三个字符串 s1, s2, s3, 求 s3 是不是由 s1 和 s2 交错组合而成。
感觉是一条比较典型的 DP 题目。
设 i, j, k 分别是 s1, s2, s3 待求解的当前下标。
- 当 s3[k] != s1[i] 且 s3[k] != s2[j], 则匹配失败
- 当 s3[k] 只和 s1[i] 相等,则 k++ 和 i++
- 当 s3[k] 只和 s2[j] 相等,则 k++ 和 j++
- 当 s3[k] == s1[i] 且 s3[k] == s2[j] ,则分别求 k++ 和 i++ ,以及 k++ 和 j++ ,两者取或运算
由于 s3 恰好有 s1 和 s2 交错行程,所以 s3 长度必然等于 s1 + s2 的长度,知道其中二者就能确定第三个数,这样只需要二维数组保存中间结果即可。
1 vector<vector<int>> vv; 2 3 bool interIleave(string s1, string s2, string s3, int p1, int p2, int p3){ 4 5 // cout << s1 << "\n" << s2 << "\n" << s3 << "\n--------\n"; 6 7 if (s1.size() == 0) { 8 return (s2 == s3); 9 } 10 11 if (s2.size() == 0) { 12 return (s1 == s3); 13 } 14 15 if (vv[p1][p3] != -1) { 16 return vv[p1][p3]; 17 } 18 19 if (s3[0] != s1[0] && s3[0] != s2[0]) { 20 vv[p1][p3] = false; 21 return false; 22 } 23 24 if (s3[0] == s1[0] && s3[0] != s2[0]) { 25 bool tmpb = interIleave(s1.substr(1), s2, s3.substr(1), p1+1, p2, p3+1); 26 vv[p1][p3] = tmpb; 27 return tmpb; 28 } 29 30 if (s3[0] != s1[0] && s3[0] == s2[0]) { 31 bool tmpb = interIleave(s1, s2.substr(1), s3.substr(1), p1, p2+1, p3+1); 32 vv[p1][p3] = tmpb; 33 return tmpb; 34 } 35 36 bool inter1 = interIleave(s1.substr(1), s2, s3.substr(1), p1+1, p2, p3+1); 37 bool inter2 = interIleave(s1, s2.substr(1), s3.substr(1), p1, p2+1, p3+1); 38 bool res = inter1 || inter2; 39 40 vv[p1][p3] = res; 41 42 return res; 43 } 44 45 46 47 bool isInterleave(string s1, string s2, string s3) { 48 49 vector<vector<int>> tmp(s1.size(), vector<int>(s3.size(), -1)); 50 vv = tmp; 51 52 if (s3.size() != s1.size()+s2.size()) { 53 return false; 54 } 55 56 if (s3.size() == 0) { 57 return true; 58 } 59 60 bool res = interIleave(s1, s2, s3, 0, 0, 0); 61 62 return res; 63 }