• 139. 单词拆分


    139. 单词拆分

    题目链接:139. 单词拆分(中等)

    给你一个字符串 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

    提示:

    • 1 <= s.length <= 300

    • 1 <= wordDict.length <= 1000

    • 1 <= wordDict[i].length <= 20

    • swordDict[i] 仅有小写英文字母组成

    • wordDict 中的所有字符串 互不相同

    解题思路

    题目中说明字典中的单词可以重复使用,并且目的是能不能拼成给定的字符串,所以这是一个完全背包问题。

    wordDict就是物品,字符串s就是背包容量,题目问单词能否拼成字符串s,其实就是物品能不能把背包装满。

    1、定义dp数组

    dp[i] : 字符串s的前i个字符组成的字符串s[0,i-1]能否被拆分成若干个字典中出现的单词。

    2、确定状态转移方程

    dp[i]之前就下面这些状态: dp[i-1],dp[i-2],...,dp[i-k],... ,但是与哪个状态有关?

    dp[i]只与dp[i-k] ,记为dp[j]有关系,其中k为s[i:j]的长度。

    我们假设: s[0:i] 字串对应dp[i+1],它是否为true取决于两点:

    它的前缀字串s[0:j-1]的dp[j],是否为true 剩余字串s[j:i],是否在单词列表里。 3、边界条件 如果字符串为空的话,说明出现在字典里。虽然看似荒谬,但是这只是为了让边界的情况也能套用状态转移方程而已。 dp[0] = true;

    4、确定dp数组的计算顺序

    一维dp数组解决完全背包问题,求组合问题先正序遍历物品,再正序遍历背包。求排列问题先正序遍历背包,再正序遍历物品。针对本题采用后者更容易写。

    C++

    class Solution {
    public:
        bool wordBreak(string s, vector<string>& wordDict) {
            unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
            vector<bool> dp(s.size() + 1, false);
            dp[0] = true;
            for (int i = 1; i <= s.size(); i++) {
                for (int j = 0; j < i; j++) {
                    string s1 = s.substr(j, i - j);
                    if (dp[j] && (wordSet.find(s1) != wordSet.end())) {
                        dp[i] = true;
                    }
                }
            }
            return dp[s.size()];
        }
    };

    JavaScript

    /**
     * @param {string} s
     * @param {string[]} wordDict
     * @return {boolean}
     */
    var wordBreak = function(s, wordDict) {
        const dp = new Array(s.length + 1).fill(false);
        dp[0] = true;
        for (let i = 1; i <= s.length; i++) {
            for (let j = 0; j < i; j++) {
                let s1 = s.slice(j, i);
                if (dp[j] && wordDict.find(obj => obj == s1)) {
                    dp[i] = true;
                }
            }
        }
        return dp[s.length];
    };

     

  • 相关阅读:
    Layui:数据表格渲染二级表头
    Layui:数据表格表头参数
    Layui:数据表格基础参数
    Layui:数据表格的渲染
    Spring+SpringMVC+MyBatis深入学习及搭建(八)——MyBatis查询缓存(转发同上)
    Spring+SpringMVC+MyBatis深入学习及搭建(六)——MyBatis关联查询(转发同上)
    Spring+SpringMVC+MyBatis深入学习及搭建(四)——MyBatis输入映射与输出映射(转发同上)
    Spring+SpringMVC+MyBatis深入学习及搭建(五)——动态sql(转发同上)
    Spring+SpringMVC+MyBatis深入学习及搭建(三)——MyBatis全局配置文件解析(转发同上)
    Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发(转发同上)
  • 原文地址:https://www.cnblogs.com/wltree/p/15978182.html
Copyright © 2020-2023  润新知