leetcode 139 单词拆分

题目

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例

输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以由 “leet” 和 “code” 拼接成。

解析

首先这道题也可以用回溯来做,这里先不管回溯了,只说动态规划;
首先翻译一下题意就是:字符串s是背包,后面那个数组是物品,且是一个完全背包问题,那么用动规五部曲分析下:
1.确认dp数组及其含义
dp[i]:字符串长度为i的话,dp[i]表示是否可以拼出来给定字符串
2.确定递推公式
在 j < i 的情况下,如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。
3.初始化
dp[0] = true,因为是根据它推出来的,不然后面的都成了false了
4.遍历顺序
趁着在这可以复习一遍之前背的遍历顺序:
如果求组合数就是外层for循环遍历物品,内层for循环遍历背包。
如果求排列数就是外层for循环遍历背包,内层for循环遍历物品。
而对于本题来说,最后求的是能否构造出xxx,其实是一个排列,比如:
s = “applepenapple”, wordDict = [“apple”, “pen”]
那么一定是物品的组合为: “apple” + “pen” + “apple” 才能组成 “applepenapple”。

func wordBreak(s string, wordDict []string) bool {
    // 单词可以重复使用,完全背包问题
    // 首先明确,s是背包,后面的那个数组是物品
    wordDictMap := make(map[string]bool)
    for _, val := range wordDict { // 注意这里遍历的是数组,每个元素可能是一个单词
        wordDictMap[val] = true  // map先全部初始化为true
    }
    dp := make([]bool, len(s)+1)
    dp[0] = true //默认一定是true
    for i := 1; i <= len(s); i++ { // 遍历背包,0没有什么遍历的必要了
        for j := 0; j < i; j++ { // 遍历物品(直接遍历小于当前背包容量的情况),想想有没有等于,虽然加上等也过了,但下面的判断条件里,后半个就没有意义了
            if dp[j] && wordDictMap[s[j:i]] {
                dp[i] = true
            }
        }
    }
    return dp[len(s)]
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值