回溯vs记忆化递归 2020-11-01(未允禁转)

2020-11-01  本文已影响0人  9_SooHyun

本文再谈一谈回溯和记忆化递归的差别

1.回溯vs记忆化递归

2.对比小结

回溯:整体解决一个问题,函数无返回值,无法储存中间结果
记忆化递归:解决一个问题=解决其子问题,函数有返回值,可以储存中间结果

而记忆化递归的逆向过程就是dp动规,显然,记忆化递归和dp是更优的方法,而回溯妥妥的就是暴力

3.例

leetcode140. 单词拆分 II

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

示例 1:
输入:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
输出:
[
"cats and dog",
"cat sand dog"
]

思路
1.回溯思路:将字典中的每一个word与s的前缀匹配,能够匹配则更新单词路径,并截取新的s通过dfs重复以上的操作。思路没错,但时间复杂度高会超时

# 回溯

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
        res = []
        # 递归的dfs回溯
        def dfs(s, wordDict, temp_res):
            nonlocal res
            # 递归出口
            if not s:
                res.append(' '.join(temp_res))
                return
            
            # 递归
            for word in wordDict:
                l = len(word)
                if s[:l] == word:
                    # 修改状态
                    temp_res.append(word)
                    # dfs
                    dfs(s[l:], wordDict, temp_res)
                    # 状态恢复
                    temp_res.pop()
        dfs(s, wordDict, [])
        return res

2.记忆化递归:定义函数dfs(s, wordDict),返回值List[str]表示s的解析结果,出口s == ''或s在字典self.d内,通过记忆中间结果避免重复计算,通过

class Solution:
    def __init__(self):
        self.d = dict()

    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:

        # 返回值List[str], 出口s == ''或s在字典self.d内
        def dfs(s, wordDict):
            # 返回[]说明不可解析,返回['']说明可解析
            
            res = []
            # 出口
            if not s:
                return ['']
            if s not in self.d:
                # 比对每个单词是否匹配s的前缀,匹配则可缩小问题规模
                for word in wordDict:
                    l = len(word)
                    if s[:l] == word:
                        ans = dfs(s[l:], wordDict)
                        # 递归式
                        if ans:
                            for sentence in ans:
                                res.append(word+ ' ' + sentence)
                self.d[s] = res
            return self.d[s]
        
        result = dfs(s, wordDict)
        # 去掉最后一个空格符
        return [s[:-1] for s in result]
上一篇 下一篇

猜你喜欢

热点阅读