给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
- 拆分时可以重复使用字典中的单词。
- 你可以假设字典中没有重复的单词。
示例 1:
**
输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以被拆分成 “leet code”。
示例 2:
**
输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以被拆分成 “apple pen apple”。
注意你可以重复使用字典中的单词。
示例 3:
输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-break
思路:
定义 dp[i]
为 0~i-1
能否被空格拆分为在字典中重复出现的数字,定义 j
为分割点,通过判断 s[j,……,i]
是否在字典中,更新 dp[i]
:如果 s[0,……,j-1]
合法, s[j,……,i-1]
也合法,那么就是可被分割的。dp[i] = dp[j] && isValid(j,i)
复杂度分析:
时间复杂度O(n) 需要遍历一遍 s
数组,复杂度O(n),枚举分割点 j
,复杂度O(n),把字典存在set中,判断只需O(1),总复杂度为O(n)
空间复杂度O(n)
var wordBreak = function(s, wordDict) {
let n = s.length;
let dp = new Array(n+1).fill(false);
let set = new Set(wordDict)
dp[0] = true;
for(let i = 1;i<=n;i++){
for(let j = 0;j < i ;j++){
if(dp[j]&&set.has(s.substr(j,i-j))){
dp[i] = true;
break;
}
}
}
return dp[n];
};