题目链接
英文链接:https://leetcode.com/problems/word-break/
中文链接:https://leetcode-cn.com/problems/word-break/
题目详述
给定一个非空字符串 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"] |
题目详解
wordDict 中的单词没有使用的次数,因此这是一个完全背包(物品可以使用0次或无限次)问题。
01 背包和完全背包的区别在于,01 背包对物品的迭代是在最外层,而完全背包对物品的迭代是在最内层。这样可以保证 01 背包最多只能使用物品一次,完全背包可以使用物品多次。
方法一:动态规划。
- boolean 数组 dp[i] 表示 s[0, i) 是否能被空格拆分为一个或多个在字典中出现的单词。例如 dp[1] 表示 s[0, 1) 也就是 s[0] 单独可以被拆分。
1 | public class LeetCode_00139 { |
可以换一种方式写动态规划,将 wordDict 转化为 HashSet,加快查找。
1 | public class LeetCode_00139 { |
方法二:DFS + 剪枝。
- s.startsWith(word, offset) 表示从 s 的 offset 处开始匹配,是否匹配。
- 设置访问标志用于剪枝。
1 | public class LeetCode_00139 { |