LeetCode Interleaving String

记忆搜索总是一个快速的方法(这里假设测试用例中s1和s2的长度都不超过(2^16) - 1 ), 当然用记忆搜索的,往往就可以写成DP的形式的,不用担心大数据时栈溢出了

#include <iostream>

#include <cstdlib>

#include <string>

#include <vector>

#include <unordered_map>



using namespace std;



class Solution {

private:

    unordered_map<unsigned int, bool> memo;

public:

    bool isInterleave(string s1, string s2, string s3) {

        memo.clear();

        return dfs(s1, 0, s2, 0, s3);

    }

    

    bool dfs(string& s1, int apos, string &s2, int bpos, string &s3) {

        unsigned int id = (apos << 16) | bpos;

        auto iter = memo.find(id);

        if (iter != memo.end()) return iter->second;

        

        int cpos = apos + bpos;

        if (apos == s1.length() && bpos == s2.length() && cpos == s3.length()) {

            memo.insert(make_pair(id, true));

            return true;

        }

        

        bool res = false;

        

        if (apos < s1.length() && s1[apos] == s3[cpos]) {

            if (dfs(s1, apos + 1, s2, bpos, s3)) {

                res = true;

            }

        }

        

        if (!res && bpos < s2.length() && s2[bpos] == s3[cpos]) {

            if (dfs(s1, apos, s2, bpos + 1, s3)) {

                res = true;

            }

        }

        

        memo.insert(make_pair(id, res));

        return res;

    }

};



int main() {



    Solution s;

    cout<<s.isInterleave("aabcc", "dbbca", "aadbbbaccc")<<endl;

    return 0;

}

 

简化dp,空间O(max(s1.len, s2.len))

class Solution {

public:

    bool isInterleave(string s1, string s2, string s3) {

        return dp(s1, s2, s3);

    }

    bool dp_helper(string &s1, string &s2, string &s3) {

        int rows = s1.length() + 1;

        int cols = s2.length() + 1;

        

        vector<bool> dp(cols, false);

        dp[0] = true;

        

        // init the dp array

        for (int i=1; i<cols; i++) {

            if (s3[i - 1] != s2[i - 1]) break;

            dp[i] = true;

        }

        

        // simplified dp using O( max(len(s1), len(s2)) ) space

        for (int i=1; i<rows; i++) {

            // whether all chars from s1 or not

            dp[0] = dp[0] && (s1[i-1] == s3[i-1]);

            for (int j=1; j<cols; j++) {

                int pos = i + j - 1;

                

                if (dp[j] && s1[i-1] == s3[pos]) {

                    // char from s1, if so, keep dp[j] unchanged( = true)

                } else if (dp[j-1] && s2[j-1] == s3[pos]) {

                    // char from s2

                    dp[j] = true;

                } else {

                    dp[j] = false;

                }

            }

        }

        return dp[cols - 1];

    }

    

    bool dp(string &s1, string &s2, string &s3) {

        int la = s1.length();

        int lb = s2.length();

        if (la + lb != s3.length()) return false;

        if (la < lb) {

            return dp_helper(s1, s2, s3);

        } else {

            return dp_helper(s2, s1, s3);

        }

    }

};

 懒得化简了

class Solution {

public:

    bool isInterleave(string s1, string s2, string s3) {

        int rows = s1.size() + 1;

        int cols = s2.size() + 1;

        int slen = s3.size();

        if (slen != s1.size() + s2.size()) {

            return false;

        }

        vector<vector<bool> > dp(rows, vector<bool>(cols, false));

        dp[0][0] = true;

        for (int i=1; i<cols; i++) {

            if (!dp[0][i-1] || s2[i-1] != s3[i-1]) {

                break;

            }

            dp[0][i] = true;

        }

        

        for (int i=1; i<rows; i++) {

            if (!dp[i-1][0] || s1[i-1] != s3[i-1]) {

                break;

            }

            dp[i][0] = true;

        }

        

        for (int i=1; i<rows; i++) {

            for (int j=1; j<cols; j++) {

                dp[i][j] = (dp[i-1][j] && s1[i-1] == s3[i + j - 1]) 

                            || (dp[i][j-1] && s2[j-1] == s3[i + j - 1]);

            }

        }

        return dp[rows-1][cols-1];

    }

};

 

你可能感兴趣的:(LeetCode)