139. 单词拆分 (记忆化dfs)

难度中等

 

给你一个字符串 s 和一个字符串列表 wordDict 作为字典,判定 s 是否可以由空格拆分为一个或多个在字典中出现的单词。

说明:拆分时可以重复使用字典中的单词。

 

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。

示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
     注意你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

 

提示:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s 和 wordDict[i] 仅有小写英文字母组成
  • wordDict 中的所有字符串 互不相同

 

记忆化 DFS

 

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        wordSet = set(wordDict)
        memo = {}
        def backtrack(s, start, wordSet):
            if start in memo:
                return memo[start]
            if start == len(s):
                memo[start] = True
                return True
            for end in range(start + 1, len(s) + 1):
                if s[start:end] in wordSet and backtrack(s, end, wordSet):
                    memo[start] = True
                    return True
            memo[start] = False
            return False

        return backtrack(s, 0, wordSet)

 

 

 

 

 

 

 

 

class Solution {
public:
    bool dfs(vector<int>& memo,int start,string& s, unordered_set<string>& word_set) {
        if (start >= s.size()) {
            return true;
        }
        if (memo[start]!=-1) return memo[start];
        
        for(int i = start; i < s.size();i++) {
            string w = s.substr(start, i-start+1);
            if (word_set.find(w) != word_set.end() && dfs(memo,i+1,s,word_set)) {
                memo[start] = 1;// true
                return true ;
            }
        }
        memo[start] = 0;// false
        return false;
    }
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> word_set;
        for(auto word :wordDict) {
            word_set.insert(word);
        }
        vector<int> memo = vector<int>(s.size(),-1);
        return dfs(memo,0,s,word_set);
    }
};

 

 

 

 

 

 

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {

        vector<bool>dp(s.size()+1,false);
        dp[0] = true;
            for(int j = 1;j <=s.size();j++) {
                for(int i = 0;i<wordDict.size();i++) {
                    auto word = wordDict[i];
                    int word_len = word.size();
                    if(j-word_len>=0 && s.substr(j-word_len,word_len)==word) {
                        dp[j] = dp[j] || dp[j-word_len];
                    }
            }
        }
        return dp[s.size()];
    }
};

 

posted @ 2021-11-08 09:24  乐乐章  阅读(220)  评论(0编辑  收藏  举报