20230705-CodeTop

66 阅读1分钟

leetcode-139 单词拆分

这题用自底向上的动态规划不是很好想,用自顶向下的记忆化搜索会好想一点。定义dp[i]为字符串从i位置开始(包含)一直到最后这段子串能否由字典组成。那么需要遍历这段子串中的每一个位置,若存在任意一个分割点j,使得s[i : j]存在于字典中且s[j : end]这段的递归结果也为真,则dp[i]为真。

class Solution {
public:
    bool dfs(int idx, vector<int>& dp, const unordered_set<string>& set, const string& s){
        if(idx == s.size()) return true;
        if(dp[idx] != 0) return dp[idx] == 1;
        bool ans = false;
        for(int i = idx; i < s.size(); ++i){
            string sub = s.substr(idx, i - idx + 1);
            if(set.count(sub)){
                ans = ans || dfs(i + 1, dp, set, s);
            }
        }
        dp[idx] = ans ? 1 : -1;
        return ans;
    }
    bool wordBreak(string s, vector<string>& wordDict) {
        int n = s.size();
        unordered_set<string> set(wordDict.begin(), wordDict.end());
        vector<int> dp(n);
        return dfs(0, dp, set, s);
    }
};