代码随想录算法训练营第四十六天| LeetCode139. 单词拆分

一、LeetCode139. 单词拆分

        1:题目描述(139. 单词拆分)

        给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

        注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

代码随想录算法训练营第四十六天| LeetCode139. 单词拆分_第1张图片

        2:解题思路

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        # 将字符串s看作背包容量,字符串列表wordDict,当做物品
        # 就是求装满这个背包,需要多少个物品,物品可以重复,就是一个完全背包的问题
        # 确定dp数组的含义:dp[i]表示能否装满容量为i的背包,及字符串长度为j是否可以拆分为一个或多个在字典中中出现的单词
        # dp[i] = True,表示可以拆分为一个或多个在字典中中出现的单词,dp[i]=False表示不可以
        # 确定递推公式
        # 如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(j < i )
        # 所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true
        # 初始化dp数组
        # 从递归公式中可以看出,dp[i] 的状态依靠 dp[j]是否为true,那么dp[0]就是递归的根基,dp[0]一定要为true,否则递归下去后面都都是false了
        # 下标非0的dp[i]初始化为false,只要没有被覆盖说明都是不可拆分为一个或多个在字典中出现的单词。
        # 确定遍历顺序,要求的是是否出现过,所以对出现单词集合里的元素是组合还是排列,并不在意,都一样
        dp = [False] * (len(s)+1)       
        dp[0] = True
        for j in range(1,len(s)+1):
            for word in wordDict:
                if j >= len(word):
                    # dp[j-len(word)] and word == s[j-len(word):j]:当前遍历的单词与字符串s截取的单词相等并且长度减去遍历单词的长度的值为True或False
                    dp[j] = dp[j] or (dp[j-len(word)] and word == s[j-len(word):j])
        return dp[len(s)]

你可能感兴趣的:(算法训练营(LeetCode),算法,leetcode,python,动态规划)