LeetCode:139. Word Break - Python

问题描述:

139. 单词拆分

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

说明:

  • 拆分时可以重复使用字典中的单词。
  • 你可以假设字典中没有重复的单词。

示例 :

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

问题分析:

   这个题目很容易想到方法就是广度优先或者深度优先来做,看了题目分类,人家是动态规划,所以现在,介绍一种动态规划的方法。要判断s 是否可以被拆分,可以先倒着分析,假设它可以被拆分,从字符串s由后向前看,后面拆分,一定是在前面被拆分的基础上完成。所以具体思路如下:

(1)设dp[i]表示字符串s[0:i]是否可以被拆分,False 不能,True能。

(2)现在要想求dp[i]的值,很显然只要判断dp[i - l]的值和子串s[i - l: i]是否存在wordDict中,其中lwordDict中一个单词的长度,所以在这一块,可以遍历所有的单词来求。

(3)可以先求出wordDict中每个长度,并且给它排序,方便后面的计算。

Python实现:

class Solution:
    def wordBreak(self, s, wordDict):
        words = set(wordDict)  # 去重
        lengths = sorted({len(w) for w in words})  # 从小到大排序

        n = len(s)
        dp = [False] * (n + 1)  # 初始化dp
        dp[0] = True
        for i in range(1, n + 1):
            for l in lengths:  # 选择单词依次判断
                if not dp[i] and i - l >= 0:
                    dp[i] = (dp[i - l] and s[i - l: i] in words)
        return dp[-1]


if __name__ == '__main__':
    solu = Solution()
    s, wordDict = "applepenapple",  ["apple", "pen"]
    print(solu.wordBreak(s, wordDict))

声明: 总结学习,有问题或不妥之处,可以批评指正哦。
题目链接、参考了他人提交的版本。

猜你喜欢

转载自blog.csdn.net/XX_123_1_RJ/article/details/82999408