单词拆分(用字典元素拼出字符串)

139. 单词拆分

在这里插入图片描述

动态规划

dp[i]代表的是能够实现str【0,i】的boolean值。
判断的是j(从【0,i】【j,i】的子字符串是否在字典中,且对应的dp[j]存在。即【0,j】子字符串可以实现,且【j,i】存在在字典中,那么当前dp[i]也可以实现,值为true。

var wordBreak = function(s, wordDict) {
    const dp = Array(s.length+1).fill(false);
    dp[0] = true;
    const hash = {};
    for(let k of wordDict) {
        hash[k] = true;
    }
    for(let i = 1; i <= s.length; i++) {
        for(let j = 0; j < i; j++) {
            let str = s.substring(j, i);
            if (dp[j] && hash[str]) {
                dp[i] = true;
                break;
            }
        }
    }
    console.log(dp)
    return dp[s.length];
};

dfs + memory记录计算过的(dp)

深度优先的方案: 用memory存储子字符串是否能实现的bollean值(减少重复计算)。
memory[i]每一项代表的是从【i,str.length-1】的子字符串的bollean值。当start值到边界说明可以实现直接返回true。
所以每一个位置的判断都是从【start, i】在字典中,且递归start = i的情况也为真则返回true.

var wordBreak = function(s, wordDict) {
    // memory(从start开始,组合成功的走到边界的dp[start]才=true)
    const dp = Array(s.length);
    const hashSet = new Set(wordDict);
    var canBreak = function (start) {
        // start移动到最后一个元素边界,成功找到结束递归
        if (s.length === start) return true;
        if (dp[start] !== undefined) return dp[start];
        for(let i = start+1; i <= s.length; i++) {
            let str = s.substring(start, i);
            if (hashSet.has(str) && canBreak(i)) {
                dp[start] = true;
                return true;
            }
        }
        dp[start] = false;
        return false;
    }
    return canBreak(0);
    console.log(dp);
};

bfs

广度优先的方案是: 维护一个元素为指针的队列,指针描述的是一个start下标对应的节点;
每次取队首元素,从start开始截取字符串【start, i】(i 【start+1, str.length】),如果当前子字符串存在在字典中,若i < len 即未到字符串边界,将当前(i下标)push进入队列中,否则说明可以实现。

var wordBreak = function(s, wordDict) {
    // visited表示当前节点访问过
    const visted = Array(s.length);
    const hashSet = new Set(wordDict);
    // 维护一个队列,依然用指针描述一个节点, start。
    const queue = [0];
    while(queue.length !== 0) {
        // 取队首元素,为start开始下标
        let start = queue.shift();
        if (visted[start]) continue;
        visted[start] = true;
        for(let i = start+1; i <= s.length; i++) {
            let str = s.substring(start, i);
            if (hashSet.has(str)) {
                if (i < s.length) {
                    queue.push(i);
                } else {
                    return true;
                }
            } 
        }
    }
    return false;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值