题目描述:
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
今日学习:
1.动规动规动动规
2.回溯
题解:天使,永远的神:https://leetcode-cn.com/problems/word-break/solution/shou-hui-tu-jie-san-chong-fang-fa-dfs-bfs-dong-tai/
//没有回溯会导致丢失很多情况,此为不正确题解
var wordBreak = function(s, wordDict) {
let temp = i = 0
while(i < s.length) {
i = temp
for(let j = i + 1; j < s.length; j++) {
let word = s.slice(i, j)
if(wordDict.indexOf(word) != -1) {
temp = j
break
}
}
if(i == temp) {
return false
}
}
return true
}
//单纯回溯还会超时,所以要加个标识
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; // start已经越界,结束递归
if (memo[start] !== undefined) return memo[start]; // memo中有,直接返回它
for (let end = start + 1; end <= s.length; end++) { // 固定start 考察所有的end
const word = s.slice(start, end); // 前缀单词
if (wordSet.has(word) && check(s, wordSet, end, memo)) {//前缀单词是单词表里的
memo[start] = true; // 并且递归剩余子串的结果也是true,则将当前结果存入memo
return true; // 当前子问题的结果是true
}
}
memo[start] = false; // 当前子问题的结果是false
return false; // start固定,end遍历了所有字符都没有返回true,则返回false
};
return check(s, wordSet, 0, memo); // 递归的入口
};
//BFS回溯
var wordBreak = function (s, wordDict) {
const wordSet = new Set(wordDict);
const visited = new Array(s.length);
const queue = [0]; // 先考察start位置0
while (queue.length) {
const start = queue.shift(); // 考察出列节点
if (visited[start] == true) continue; // 跳过访问过的
visited[start] = true; // 访问了 记录一下
for (let end = start + 1; end <= s.length; end++) { // 固定start 考察所有end
const word = s.slice(start, end); // 开头的单词
if (wordSet.has(word)) { // 单词表有这个单词
if (end > s.length - 1) return true; // 并且end已经越界,说明考察完了s串
queue.push(end); // 将下一层的end推入队列
}
}
}
return false;
};
//动规
var wordBreak = function (s, wordDict) {
const wordSet = new Set(wordDict);
const len = s.length;
const dp = new Array(len + 1).fill(false);
dp[0] = true;
for (let i = 1; i <= len; i++) {
for (let j = i; j >= 0; j--) {
const word = s.slice(j, i);
if (wordSet.has(word) && dp[j] == true) {
dp[i] = true;
break;
}
}
}
return dp[s.length];
};