单词拆分

198 阅读2分钟

题目

给定一个字符串 s 和一个字符串字典 wordDict ,在字符串 s 中增加空格来构建一个句子,使得句子中所有的单词都在词典中。以任意顺序 返回所有这些可能的句子。 注意:词典中的同一个单词可能在分段中被重复使用多次。

  • 示例 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"]
输出:[]

题目来源:LeetCode

思路1

let s = "pineapplepenapple", wordDict = ["apple", "pen", "applepen", "pine", "pineapple"];

分情况讨论

  • 第一步 s ===(是否含apple)====> (包含但是word位置不匹配)

s ===(是否含pen)====> (包含但是word位置不匹配)

s ===(是否含applepen)====> (包含但是word位置不匹配)

s ===(是否含pine)====> (包含但是word位置匹配)==> 结果1:[pine],剩余部分:applepenapple

s ===(是否含pineapple)====> (包含但是word位置匹配) 结果2:[pineapple],剩余部分:penapple

  • 第二步

情况1:接口 applepenapple === 循环匹配["apple", "pen", "applepen", "pine", "pineapple"] ==> 结果1:[pine ,apple],剩余部分:penapple、 结果2:[pine ,applepen],剩余部分:apple

情况2:接口 penapple === 循环匹配["apple", "pen", "applepen", "pine", "pineapple"] ==>结果3:[pineapple,pen],剩余部分:apple

  • 第三部(第二部调用)

结果1:[pine ,apple],剩余部分:penapple ==>调用(第二步)==>[pine ,apple,pen]==>调用(第二步)==>[pine ,apple,pen,apple]

结果2:[pine ,applepen],剩余部分:apple == >调用(第二步)==[pine ,applepen,apple]`

结果3:[pineapple,pen],剩余部分:apple== >调用(第二步)==[pineapple,pen,apple]`

代码实现


function wordBreak(s, wordDict) {
  let results = [];
  for (let i = 0; i < wordDict.length; i++) {
    const element = wordDict[i],
      index = s.indexOf(element),
      remian = s.replace(element, "");
    if (index == 0) {
      if (remian && remian.length > 0) {
        _deep(remian, wordDict, [element], results);
      } else {
        results = [s];
      }
    }
  }
  return results;
}
function _deep(remian, wordDict, arr, results) {
  for (let i = 0; i < wordDict.length; i++) {
    const element = wordDict[i],
      index = remian.indexOf(element),
      remian_ = remian.replace(element, "");
    if (index == 0) {
      if (remian_ && remian_.length > 0) {
        _deep(remian_, wordDict, [...arr, element], results);
      } else {
        results.push([...arr, element].join(" "));
      }
    }
  }
}

运行结果

1655451820020.png

思路2

let s = "pineapplepenapple", wordDict = ["apple", "pen", "applepen", "pine", "pineapple"];

  • 过滤wordDict

通过s开头一个字母p 过滤可以匹配的项目 [pen,pine,pineapple]

获取wordDict数组中最大字符串的长度

  • 第二步 匹配字符串

循环最大字符串的长度 ,从s截取字符串去匹配 [pen,pine,pineapple]*第二步 得到 结果1:[{wrod:'pine',remain:'applepenapple'},{wrod:'pineapple',remain:'penapple'}]

*第三部 处理余下字符串(递归调用一、二)

根据结果1可以得到两个过滤wordDict分别是[apple,applepen][pen,pineapple,pine]

在获取过滤wordDict 最大的字符串长度

循环最大字符串的长度 ,匹配剩余字符串 [{wrod:'pine apple',remain:'penapple'},{wrod:'pine applepen',remain:'apple'}{wrod:'pineapple pen',remain:'apple'}]

  • 在循环做第三部 递归输出结果

思路2 不在贴代码,自己可以试一试实现