LeetCode 139.单词分割 题解
题目描述
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
1 | 输入: s = "leetcode", wordDict = ["leet", "code"] |
示例 2:
1 | 输入: s = "applepenapple", wordDict = ["apple", "pen"] |
示例 3:
1 | 输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] |
算法1
(DP) $O(n^3)$
分析:
题目意思是需要使用给定的字典中的单词拼接出目标字符串,可以将题目抽象为: 将一个字符串分割成为若干部分,使得每一部分都能够在字典中找到
因此,首先需要使用一个哈希表来存储所有的字典中的单词,方便后续查找划分出的部分是否在字典中
其次,我们可以发现,每种划分方法代表的是一种状态下的方案,而不是单单某一种方案,因此需要可以考虑使用 DP 来计算当前划分方案是否合法
DP
- 集合:定义
f[i]
为从1 ~ i
是否是一种合理的划分方案 - 属性:
bool
,判断当前的划分方案是否合法 - 转移: 针对当前的起点 i, 终点 j,如果
s[i ~ j]
存在于字典中,那么,当前划分方案是否合法取决于1 ~ i - 1
是否合法,而根据定义,1 ~ i - 1
的合法性刚好就是f[i - 1]
1 | class Solution { |
注:
- 关于此处代码中的
f[i]
,是为了计算方便,从后往前搜索的,与正常的思维逆反过来即可 - 按照相反的定义
f[n] 表示从 n ~ n
的方案合法性 - 那么
f[i]
的合法性同理的,由s[i, j]
和f[j + 1]
共同决定
算法2
(DP + 字符串哈希) $O(n^2)$
由于朴素的 DP 算法中,每次需要调用 substr
来取得某一段的字符串值,但是这样的话复杂度与那一段的长度相关,因此会造成复杂度上升,因此,需要考虑一种方法将这个过程的复杂度降低
可以考虑字符串哈希的方法,将字典中的所有字符串映射成为 P 进制的数,同时,在将字符串进行划分时,也映射成为相应进制的数字,这样可以在 $O(1)$ 的时间内判断字符串是否在字典之中,成功优化时间复杂度
1 | class Solution { |
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.