代码随想录第三十九天|单词拆分|背包问题总结

单词拆分

转换为背包问题;单词字典就是物品,字符串就是背包,看字典里的单词能不能拼接出字符串,就是用单词能不能装满字符串长度的背包。

递推五部曲;

  1. dp[j]代表的是字符串长度为j,若能由单词字典里的单词拼接而成,则dp[j]为true
  2. 递推公式:如果dp[j]是true,那么在[j,i]的区间的子串也能从单词字典中取得,那么dp[i]也为true,
  3. 所以递推公式为:if([i,j]的子串出现在单词字典中&&dp[j]=true)则dp[i]也为true。
  4. 初始化:dp[0]=true,其它的都为false
  5. 遍历顺序:这里虽然是只求能不能装满背包,但是这个字符串也是有顺序的,必须按照字符串的顺序进行拼接。所以需要用排列的方法
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        boolean[] dp=new boolean[s.length()+1];
        Arrays.fill(dp,false);
        dp[0]=true;
        Set<String> set=new HashSet();
        for(String str:wordDict){
            set.add(str);
        }
        for(int j=1;j<s.length()+1;j++){
            for(int i=0;i<j;i++){
                String str=s.substring(i,j);
                if(set.contains(str)&&dp[i]){
                    dp[j]=true;
                }

            }
        }
        return dp[s.length()];
    }
}

背包问题总结

01背包,每种物品只能使用一次,在遍历背包的时候,需要倒序遍历,而且只能先遍历物品,再遍历背包,顺序不能颠倒,因为需要倒序遍历,如果颠倒的话会导致每个背包中只有一件物品。

完全背包,每种物品能使用多次,那就接触倒序遍历的限制,然后遍历顺序也能够颠倒。但是在特定的问题中遍历顺序也是有讲究的

完全背包可以分为以下几种问题:

  • 装满指定容量的背包,有多少种装满的方式,那这里有多少种装满的方式,那这里就设置组合和排列的区别,需要根据题意来确定是选择排列还是组合,若是组合的话,遍历顺序为先物品后背包,保证先加入背包的物品一直排在前面。而若是排列的话,遍历顺序就为先背包后物品,这样的话先放入的物品,在背包容量变大时重新加入背包的时候可以排在后面,就是排列了。dp[j] +=dp[j-nums[i]];
  • 能否装满指定容量的背包,或者是最多能装多少,dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
  • 装满指定容量的背包的最大价值,dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
  • 装满指定容量的背包的最小物品数,dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值