6.5 零钱兑换1、2 && 组合总和

零钱兑换1

思想:完全背包,只是求最小硬币数

那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数

所以本题并不强调集合是组合还是排列。

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

本题钱币数量可以无限使用,那么是完全背包。所以遍历的内循环是正序

    public int coinChange(int[] coins, int amount) {
    	//总金额为j时的最少硬币数为dp[j]
        if(amount==0)return 0;
    	int[] dp=new int[amount+1];
        //初始化,如果只是初始化了dp[0]呢么最后的结果一定被初始值0覆盖,因为每次求得都是min
        //因为状态方程是min,初始化一个最坏的情况,也就是无解
    	Arrays.fill(dp, amount+1);
    	dp[0]=0;
    	for(int i=0; i<coins.length; i++)
    		//完全背包,内层循环正序遍历
    		for(int j=coins[i]; j<=amount; j++) {
    			dp[j]=Math.min(dp[j], dp[j-coins[i]]+1);
    		}
            //dp[amount]==amount+1就是无解的情况
    	return dp[amount]==amount+1 ? -1:dp[amount];
    }

零钱兑换2

思想:完全背包、组合数(外层物品,内层背包)

	 public int change(int amount, int[] coins) {
    	//总金额为j时的组合数为dp[j]
    	int[] dp=new int[amount+1];
    	//金额为0的组合就1种
    	dp[0]=1;
    	//组合数
    	for(int i=0; i<coins.length; i++)
    		for(int j=coins[i]; j<=amount; j++) {
    			dp[j]+=dp[j-coins[i]];
    		}
    	return dp[amount];
    }

组合总和4

思想:完全背包、排列数(外层背包,内层物品)

既然递归公式是 dp[i] += dp[i - j],那么dp[0] 一定为1,dp[0]是递归中一切数值的基础所在,如果dp[0]是0的话,其他数值都是0了。

    public int combinationSum4(int[] nums, int target) {
    	//总和为j时的排列数为dp[i]
    	int[] dp=new int[target+1];
    	//和为0的组合就1种
    	dp[0]=1;
    	//排列数
    	for(int i=1; i<=target; i++)
    		for(int j=0; j<nums.length; j++) {
    			if(i>=nums[j])dp[i]+=dp[i-nums[j]];
    		}
    	return dp[target];
    }

回文子串

思想:中心拓展法。和最长回文子串类似,但是要注释掉只向左拓展(或者只向右边拓展),不然像s="aaa"就会重复计算同一回文子串

    public int countSubstrings(String s) {
    	int count=0;
    	int len=s.length();
    	int left,right;
    	for(int i=0; i<len; i++) {
    		count++;
    		left=i-1;
    		right=i+1;
    		while(left>=0 && s.charAt(i)==s.charAt(left)) {
    			count++;
    			left--;
    		}
//    		while(right<len && s.charAt(i)==s.charAt(right)) {
//    			count++;
//    			right++;
//    		}
    		while(left>=0 && right<len && s.charAt(right)==s.charAt(left)) {
    			count++;
    			right++;
    			left--;
    		}
    	}
    	return count;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值