单词拆分

单词拆分

CategoryDifficultyLikesDislikes
algorithmsMedium (54.22%)2231-
Tags

dynamic-programming

Companies

amazon | bloomberg | facebook | google | pocketgems | uber | yahoo

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

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

示例 1:

1
2
3
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。

示例 2:

1
2
3
4
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。
     注意,你可以重复使用字典中的单词。

示例 3:

1
2
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

提示:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • swordDict[i] 仅有小写英文字母组成
  • wordDict 中的所有字符串 互不相同

Discussion | Solution

解法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// @lc code=start
impl Solution {
    /// ## 解题思路
    /// - 动态规划
    /// 1. 设 dp[i]: 表示s[..i]是否能成功进行单词拆分;
    /// 2. 目标: dp[n] (n=s.len())
    /// 3. 递推关系:
    ///     dp[i+l] = true  ( dp[i] && s[i..(i+l)] in word_dict)
    /// 4. 初始条件:
    ///     dp[0] = true
    pub fn word_break(s: String, word_dict: Vec<String>) -> bool {
        use std::collections::HashSet;
        let word_dict = word_dict.into_iter().collect::<HashSet<String>>();

        let n = s.len();
        let mut dp = vec![false; n + 1];
        dp[0] = true;
        for i in 0..n {
            for l in word_dict.iter().map(|w| w.len()) {
                if dp[i] && i + l <= n && word_dict.contains(&s[i..(i + l)].to_string()) {
                    dp[i + l] = true;
                }
            }
        }

        dp[n]
    }
}
// @lc code=end

updatedupdated2024-05-102024-05-10