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

    1. var wordBreak = function(s, wordDict) {
    2. let n = s.length;
    3. let dp = new Array(n+1).fill(false);
    4. let set = new Set(wordDict)
    5. dp[0] = true;
    6. for(let i = 1;i<=n;i++){
    7. for(let j = 0;j < i ;j++){
    8. if(dp[j]&&set.has(s.substr(j,i-j))){
    9. dp[i] = true;
    10. break;
    11. }
    12. }
    13. }
    14. return dp[n];
    15. };