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.
#include <iostream> #include <string> #include <vector> /** Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example, Given: s1 = "aabcc", s2 = "dbbca", a a b c c d b b c a When s3 = "aadbbcbcac", return true. When s3 = "aadbbbaccc", return false. 思路:把s1和s2理解成图,然后进行遍历 a -> a - > b -> c - >c 结点之间全联通 d -> b -> b -> c - > a DFS其实就是暴力的思路来求解,所以在大数据不能AC DFS的复杂度是:最坏情况下遍历了所有的边 M和N的指数相关,如果相对于M来说,N^M 爆炸级别的遍历 所以明显里面包含了很多dp的节奏 实际情况是,每次进去之前都会判断,相当于做了 tuning. 这个DFS也可以用存储格的思路减少重复的计算 @ihasleetcode 给出了dp的解决办法 dp[i,j] = whether s3[i+j] can be interleaved by s1[0,i] and s2[0,j] dp[i,j] = dp[i-1,j] && s2[i+j -1] == s1[i-1] || dp[i,j-1] && s3[i + j -1] == s2[j - 1] */ using namespace std; class Solution { public: //从前往后找就是在搜素 bool dfs(string s1, int pos1, string s2, int pos2, string s3){ if (pos1 == s1.size() && pos2 == s2.size() && pos1 + pos2 == s3.size()){ return true; } bool ans; if (pos1 < s1.size() && s1[pos1] == s3[pos1 + pos2]){ ans = dfs(s1,pos1 + 1, s2, pos2, s3); if (ans) return ans; } if (pos2 < s2.size() && s2[pos2] == s3[pos1 + pos2]){ ans = dfs(s1,pos1, s2, pos2+ 1, s3); if (ans) return ans; } return false; } //从后往前找 dfs+cache bool dfs_cache(string s1,int p1, string s2, int p2){ } bool isInterleave(string s1, string s2, string s3) { //return dfs(s1,0,s2,0,s3,0); if (s1.empty()){ return s2 == s3; } if (s2.empty()){ return s1 == s3; } return dp(s1,s2,s3); } bool dp(string s1, string s2, string s3){ if (s3.size() != s1.size() + s2.size()) { return false; } vector<vector<bool> > dp; dp.resize(s1.size() + 1); for(int i = 0; i < s1.size() + 1; i++){ dp[i].resize(s2.size() + 1,false); dp[i][0] = true; } for(int i = 0; i <= s1.size(); i++){ for(int j = 0; j <= s2.size(); j++){ if (i && s3[i + j -1] == s1[i -1] && dp[i-1][j]){ dp[i][j] = true; } if (j && s3[i + j -1] == s2[j -1] && dp[i][j-1]){ dp[i][j] = true; } } } return dp[s1.size()][s2.size()]; } //可以进一步做压缩,2个变量就足够 bool dp3(string s1, string s2, string s3) { // Start typing your C/C++ solution below // DO NOT write int main() function if (s3.size() != s1.size() + s2.size()) { return false; } vector<bool> dp; dp.resize(s2.size() + 1,false); int i ,j; dp[0] = true; for (i = 0; i <= s1.size(); ++i) { //第一行从1开始,以后从0开始? for (j = i?0:1; j <= s2.size(); ++j) { dp[j] = (i && dp[j] && (s1[i - 1] == s3[i + j - 1])) || (j && dp[j - 1] && (s2[j - 1] == s3[i + j - 1])); } } return dp[s2.size()]; } //2个变量的版本 }; using namespace std; int main(int argc, char *argv[]) { Solution sol; string s1 = "aabcc"; string s2 = "dbbca"; string s3 = "aadbbcbcac"; string s4 = "aadbbbaccc"; cout << sol.isInterleave(s1,s2,s3); }