题目

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.

Note:

  • The same word in the dictionary may be reused multiple times in the segmentation.
  • You may assume the dictionary does not contain duplicate words.

Example 1:

  1. Input:
  2. s = "catsanddog"
  3. wordDict = ["cat", "cats", "and", "sand", "dog"]
  4. Output:
  5. [
  6. "cats and dog",
  7. "cat sand dog"
  8. ]

Example 2:

  1. Input:
  2. s = "pineapplepenapple"
  3. wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
  4. Output:
  5. [
  6. "pine apple pen apple",
  7. "pineapple pen apple",
  8. "pine applepen apple"
  9. ]
  10. Explanation: Note that you are allowed to reuse a dictionary word.

Example 3:

  1. Input:
  2. s = "catsandog"
  3. wordDict = ["cats", "dog", "sand", "and", "cat"]
  4. Output:
  5. []

题意

判断给定字符串按照某种方式分割后得到的所有子串能否在给定数组中找到,并返回所有可能的分割方式。

思路

139. Word Break (M) 威力加强版。使用记忆化DFS搜索处理。在139题的基础上进行改动:HashMap记录字符串s中以下标start为起点的子字符串的所有分割方式(如果无法有效分割则为空)。


代码实现

Java

  1. class Solution {
  2. Map<Integer, List<String>> hash = new HashMap<>();
  3. public List<String> wordBreak(String s, List<String> wordDict) {
  4. return dfs(s, 0, wordDict);
  5. }
  6. private List<String> dfs(String s, int start, List<String> wordDict) {
  7. if (hash.containsKey(start)) {
  8. return hash.get(start);
  9. }
  10. List<String> res = new ArrayList<>();
  11. // 边界处理,说明这种分割方式有效,添加空字符串方便处理
  12. if (start == s.length()) {
  13. res.add("");
  14. return res;
  15. }
  16. for (String word : wordDict) {
  17. // 每次先找到下一个能有效分割的位置
  18. if (s.substring(start).startsWith(word)) {
  19. List<String> next = dfs(s, start + word.length(), wordDict);
  20. for (String t : next) {
  21. // 注意空格的处理
  22. if (!t.isEmpty()) {
  23. t = " " + t;
  24. }
  25. res.add(word + t);
  26. }
  27. }
  28. }
  29. // 如果以start为起点的子串不能有效分割,则返回的res是一个空list
  30. hash.put(start, res);
  31. return res;
  32. }
  33. }

JavaScript

  1. /**
  2. * @param {string} s
  3. * @param {string[]} wordDict
  4. * @return {string[]}
  5. */
  6. var wordBreak = function (s, wordDict) {
  7. return dfs(s, 0, new Map([[s.length, [[]]]]), wordDict).map(v => v.join(' '))
  8. }
  9. let dfs = function (s, index, record, wordDict) {
  10. if (record.has(index)) {
  11. return record.get(index)
  12. }
  13. let lists = []
  14. for (let word of wordDict) {
  15. if (s.slice(index).startsWith(word)) {
  16. let next = dfs(s, index + word.length, record, wordDict)
  17. for (let list of next) {
  18. let tmp = [...list]
  19. tmp.unshift(word)
  20. lists.push(tmp)
  21. }
  22. }
  23. }
  24. record.set(index, lists)
  25. return lists
  26. }