leetcode-单词拆分 II

107 阅读2分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

题目描述

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

说明:

  • 分隔时可以重复使用字典中的单词。

  • 你可以假设字典中没有重复的单词。

  • 示例 1:

输入:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
输出:
[
  "cats and dog",
  "cat sand dog"
]
  • 示例 2:
输入:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
输出:
[
  "pine apple pen apple",
  "pineapple pen apple",
  "pine applepen apple"
]
  • 示例 3:
输入: s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: []
  • 提示:
1 <= s.length <= 300
1 <= wordDict.length <= 1000
1 <= wordDict[i].length <= 20
s 和 wordDict[i] 仅有小写英文字母组成
wordDict 中的所有字符串 互不相同

实现思路

这道题我们使用回溯算法来解决,通过切割字符串s来跟数组wordDict来匹配如果切割完的字符串都有在数组中说明符合题意添加进结果集合。

代码实现过程:

  1. 定义set来存储wordDict数组值,用来验证切割的字符串是否在wordDict中
  2. 定义res用来存储符合条件的字符串
  3. 定义递归函数fn,当index == s.length说明s字符串切割完成并符合题意将list添加进结果集合res
  4. for循环切割字符串当字符串有数组中回调继续往下切割直到index == s.length
  5. 如果切割的字符串在set中将str和list合并成新list进入fn回调往后切割s
  6. 调用回调函数fn从头开始切割匹配fn(0)返回答案res
/**
 * @param {string} s
 * @param {string[]} wordDict
 * @return {string[]}
 */
var wordBreak = function(s, wordDict) {
    let set = new Set(wordDict)
    let res = []
    let fn = function(index, list) {
        if (index == s.length) {
            res.push(list.join(' '))
        }
        for (let i = index; i < s.length; i++) {
            let str = s.substring(index, i + 1)
            if (set.has(str)) {
                fn(i+1, [...list, str])
            }
        }
    }
    fn(0, [])
    return res
};