刷题笔记0x09:单词拆分
创建于:发布于:文集:随笔
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。https://leetcode-cn.com/problems/word-break/
这个题目一开始被我误解成是判断列表中的字符串是否都是s
的子串,最后看到官方示例才纠正回来~
可以发觉,这个题目我们是要找出断点打断字符串s
,让打断后的各个单词都在单词列表中。
下面分析一下,如果我们有一个长度为i
的字符串,那么假设dp[j]
表示字符串到j
位置的子字符串是否符合题目条件,可以得出,如果dp[i]
也就是长度为i
的原字符串s
符合条件,那么一定有一个0 < j < i
的情况下,dp[j]
符合条件,并且,剩下的j
到i
的部分是在单词列表里面的。
通过分析我们发现这是一个可以用动态规划解决的问题,状态转移方程为:
// 伪代码
dp[i] = dp[j] and (s[j:i] in wordDict)
在具体代码中,我们设dp
数组长度为s长度加一,dp[0]
设为真做初始条件,从i=1
开始迭代。
最后成功超越100%,不过这和Leetcode上用Rust
刷题的少也有关系。
我们的代码还有优化的空间,不过由于现在耗时四舍五入0ms了,为了展示差别,用Python
演示下(这样感觉Python很没有排面啊:
先上个普通Python版:
由于线性表查找时间复杂度为O(N)
,而哈希表查找时间复杂度为O(1)
,所有我们利用字典生成式将原本的单词列表转成哈希结构的字典:
快了一丢丢~
评论区也有先求出wordDict
中最长单词长度maxWordLength
,仅遍历当前i
位置向前maxWordLength
的元素,以减少循环次数,不过我试了几次运行时间没有显著提升。