一天一大 leet(单词拆分)难度:中等 DAY-25

时间:2022-07-25
本文章向大家介绍一天一大 leet(单词拆分)难度:中等 DAY-25,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目(难度:中等):

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

说明:

  • 拆分时可以重复使用字典中的单词。
  • 你可以假设字典中没有重复的单词。

示例

  1. 示例1
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。
  1. 示例2
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
     注意你可以重复使用字典中的单词。
  1. 示例3
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

抛砖引玉

特殊情况

  • s为空 true
  • s长度为1 判断wordDict是否包含该字符串

查找规律

  • s长度为2时:
    • wordDict中是否包含第一个字符,使用数组存储几个:_result[1]
    • wordDict中是否包含第二个字符:_result[2]
    • wordDict中是否包含两个字母的组合,即前0个字母与之后的两个字母组合:_result[0]&&s.substring(0, 2); 只要上面一种情况满足就满足
  • s长度为n时:
    • wordDict中是否包含第n-1个字符:_result[n-1]
    • wordDict中是否包含第一个字符,使用数组存储几个:_result[1]
    • wordDict中是否包含第二个字符:_result[2]
    • ...
    • wordDict中是否包含x个字母的组合,即前n-x个字母与之后的x个字母组合:_result[x]&&s.substring(x, n+1);

代码实现

当想要知道长n的字符串S是否满足是,默认已经知道了前n个字符组合的结果,这样追溯一直会追溯到长0 当前n个字母结果与剩余字符组合在wordDict则满足条件

/**
 * @param {string} s
 * @param {string[]} wordDict
 * @return {boolean}
 */
var wordBreak = function(s, wordDict) {
  let _result = new Array(s.length + 1).fill(false);
  _result[0] = true;
  for (let i = 0; i <= s.length; i++) {
    for (let j = 0; j < i; j++) {
      if (_result[j] && wordDict.includes(s.substring(j, i))) {
        _result[i] = true;
        break
      }
    }
  }
  return _result[s.length]
};

其他解法

  • 借助递归完成前n-1次或的判断
  • 递归的跳出条件是递归指定的开始字符等于s.length或者遇到满足条件的匹配条件
/**
 * @param {string} s
 * @param {string[]} wordDict
 * @return {boolean}
 */
var wordBreak = function(s, wordDict) {
  const wordSet = new Set(wordDict);
  const memo = new Array(s.length);
  const check = (s, wordSet, start, memo) => {
    if (start > s.length - 1) return true;
    if (memo[start] !== undefined) return memo[start];
    for (let end = start + 1; end <= s.length; end++) {
      const word = s.slice(start, end);
      if (wordSet.has(word) && check(s, wordSet, end, memo)) {
        memo[start] = true;
        return true;
      }
    }
    memo[start] = false;
    return false;
  };
  return check(s, wordSet, 0, memo);
};