0
点赞
收藏
分享

微信扫一扫

LeetCode - 解题笔记 - 140 - Word Break II

老罗话编程 2022-02-19 阅读 73

Solution 1

显然是对 0139. Word Break 的延申,有效性判定变成结果搜索,从头开始逐个单词的匹配。

难点:直接使用DFS会出现大量的重复计算,使用记忆化搜索改进

记忆化搜索:引入一个哈希表,保存索引 i i i向后之后缀的所有方案

边界判定:如果到达结尾,答案缺省为空串,使用空格拼接时用以判断

可以用的剪枝:如果未确定长度不满足任何一个单词,直接跳过(未实现)

  • 时间复杂度: O ( n ⋅ 2 n ) O(n \cdot 2^n) O(n2n),其中 n n n为输入字符串的长度。最坏情况下,每个位置都会划分考察并进行计算,每一个结果的子串需要 O ( n ) O(n) O(n)的生成时间
  • 空间复杂度: O ( n ⋅ 2 n ) O(n \cdot 2^n) O(n2n),其中 n n n为输入字符串的长度。对应地,最坏情况下需要同等规模的空间占用(每个子串方案都需要 O ( n ) O(n) O(n)的空间)
class Solution {
public:
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        unordered_map<int, vector<string>> strDict;
        auto wordSet = unordered_set(wordDict.begin(), wordDict.end());
        this->search(s, 0, wordSet, strDict);
        return strDict[0];
    }
    
private:
    void search(string s, int start, unordered_set<string>& wordSet, unordered_map<int, vector<string>>& strDict) {
        // 记忆化搜索:如果当前子串已经完成了分析,直接返回
        if (strDict.find(start) == strDict.end()) {
            if (start == s.size()) {
                // 结尾空串
                strDict[start] = {""};
                return;
            }
            
            strDict[start] = vector<string> ();
            
            for (int i = start + 1; i <= s.size(); ++i) {
                // 从start开始,枚举所有可能的第一个词
                auto str = s.substr(start, i - start);
                if (wordSet.find(str) != wordSet.end()) {
                    this->search(s, i, wordSet, strDict); // 继续向下递归,然后同样地调整strDict保存的内容
                    // 利用后缀更新当前strDict的内容
                    for (auto item: strDict[i]) {
                        if (!item.empty()) {
                            // 结尾空串
                            strDict[start].push_back(str + " " + item);
                        } else {
                            strDict[start].push_back(str);
                        }
                    }
                }
            }
        }
    }
};

Solution 2

Solution 1的Python实现

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
        wordSet = set(wordDict)
        strDict = dict()
        
        def search(start: int) -> None:
            # nonlocal wordSet
            # nonlocal strDict
            if start not in strDict:
                if start == len(s):
                    strDict[start] = [""]
                    return
                    
                strDict[start] = list()
                for i in range(start + 1, len(s) + 1):
                    word = s[start: i]
                    if word in wordSet:
                        search(i)
                        for item in strDict[i]:
                            if item == "":
                                strDict[start].append(word)
                            else:
                                strDict[start].append(word + " " + item)
        

        search(0)
        return strDict[0]
举报

相关推荐

0 条评论