• leetcode每日一题(2020-06-25):139. 单词拆分


    题目描述:
    给定一个非空字符串 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];
    };
    
  • 相关阅读:
    【京东面试复盘】一面二面真题面经解析
    4个小技巧带你轻松入门kafka!
    python 函数
    python 文件修改
    python 文件基本操作
    python 集合的一些用法
    python 字典的应用_简单的三级列表
    python 字典的一些用法
    python 字符串的一些用法
    python 列表应用-简单的购物车
  • 原文地址:https://www.cnblogs.com/autumn-starrysky/p/13191389.html
Copyright © 2020-2023  润新知