动态规划第三天

leetcode 学习计划 动态规划第三天

1.打家劫舍

题目地址
这题第k家的最大值为(盗取第k-2的最大值+盗取第k家所得的钱) 和 (盗取第k-1家的最大值) 的最大值,动态转移方程如下

dp(k)=max(dp(k-1),dp(k-2)+nums[k]);

代码如下

public int rob(int[] nums) {
    if (nums.length == 1) {
        return nums[0];
    }
    int[] dp = new int[nums.length];
    dp[0] = nums[0];
    dp[1] = Math.max(nums[0], nums[1]);
    for (int i = 2; i < nums.length; i++) {
        dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
    }
    return dp[nums.length - 1];
}

2.打家劫舍Ⅱ

题目地址
这题目和上一题的区别就是第一家和最后一家不能同时打劫。所以我们只要取从第0家打劫到第nums.length-1 和从第1家打劫到第nums.length 家的最大的值。

public int rob(int[] nums) {
    if(nums.length==1){
        return nums[0];
    }
    if(nums.length==2){
        return Math.max(nums[0],nums[1]);
    }
    return Math.max(robtmp(nums,0,nums.length-2),robtmp(nums,1,nums.length-1));
}

public int robtmp(int[] nums,int start,int end) {
    int a = nums[start];
    int b = Math.max(nums[start], nums[start + 1]);
    int temp;
    for (int i = start + 2; i <= end; i++) {
       	temp = b;
        b = Math.max(a + nums[i], b);
        a = temp;
    }
    return b;
}

3.删除并获得点数

这题可以转化为第一题。当nums[i]看作新的数组的下标,所有等于nums[i]的和看作新数组的值,就转换为了第一题。
这里用下stream流,问就是看起来帅,但是实际速度比for循环低了很多,这点可以研究下,不过那次看strem流源码没怎么看懂,我还是太菜。
我们先求出新数组的长度,即元素组元素的最大值+1

Arrays.stream(nums).max().orElse(0) + 1

接着求出新数组的元素值

Arrays.stream(nums).forEach(num->sum[num]+=num), 此处sum就是新数组
public int deleteAndEarn(int[] nums) {
    int[] sum = new int[Arrays.stream(nums).max().orElse(0) + 1];
    Arrays.stream(nums).forEach(num->sum[num]+=num);
    return rob(sum);
}

public int rob(int[] nums) {
    int a = nums[0];
    int b = Math.max(nums[0], nums[1]);
    for (int i = 2; i < nums.length; i++) {
        int temp = b;
        b = Math.max(a + nums[i], b);
        a = temp;
    }
    return b;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值