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