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

20200625

img

题目(难度:中等):

给定一个非空字符串 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

抛砖引玉

img

特殊情况
  • s为空 true
  • s长度为1 判断wordDict是否包含该字符串
查找规律
  • s长度为2时:
    • wordDict中是否包含第一个字符,使用数组存储几个:_result[1]
    • wordDict中是否包含第二个字符:_result[2]
    • wordDict中是否包含两个字母的组合,即前0个字母与之后的两个字母组合:_result[0]&&s.substring(0, 2);
      只要上面一种情况满足就满足
  • s长度为n时:
    • wordDict中是否包含第一个字符,使用数组存储几个:_result[1]
    • wordDict中是否包含第二个字符:_result[2]
      • wordDict中是否包含第n-1个字符:_result[n-1]
    • 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);
};

博客: 小书童博客(http://gaowenju.com)

公号: 坑人的小书童
坑人的小书童

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值