【LeetCode】198. House Robber[Medium]

题目链接:打家劫舍

题目描述:一个非负整数数组,相邻的两个数不能相加,求最大的和是多少。

思路:

一、最开始分析找规律找到的情况是,因为相邻的数不能相加,所以第i个数只能在之后加上第i+2或第i+3个数。哪个大加哪个。

所以,到第i个数的和,只跟第i-2和第i-3个数有关。即sum[i]=Max(sum[i-2],sum[i-3])+nums[i]。

时间O(n),空间O(1)

JavaScript代码如下:

var rob = function(nums) {
    const len=nums.length;
    if(len==1)
        return nums[0];
    if(len==2)
        return nums[0]>nums[1]?nums[0]:nums[1];
    if(len==3)
        return nums[0]+nums[2]>nums[1]?nums[0]+nums[2]:nums[1];
    let max=0;
    for(let i=2;i<nums.length;i++){
        if(i==2){
            nums[2]+=nums[0];
            if(nums[2]>max)
                max=nums[2];
        }   
        else{
            nums[i]=nums[i-2]+nums[i]>nums[i-3]+nums[i]?nums[i-2]+nums[i]:nums[i-3]+nums[i];
            if(nums[i]>max)
                max=nums[i];
        }
    }
    return max;
};

二、看完题解之后仔细分析,发现这是一个简单的动态规划

n个数的最大和,有两种情况,取第n个数,那么和是n-2个数的最大和加上第n个数,不取第n个数,那么和是n-1个数的最大和。

即状态转移方程为:dp[n]=Max(dp[n-1],dp[n-2]+nums[n-1])。

边界条件是dp[0]=0,dp[1]=nums[0]。

因为dp[n]只和前面的两个数dp[n-1],dp[n-2]有关。所以没必要开一个动态规划数组,只需要两个变量动态维护即可。时间O(n),空间O(1)。

JavaScript代码:

const length=nums.length;
    if(length==0)
        return 0;
    if(length==1)
        return nums[0];
    let a=0,b=nums[0];
    let tep;
    for(let i=2;i<=length;i++){
        tep=b>a+nums[i-1]?b:a+nums[i-1];
        a=b;
        b=tep;
    }
    return tep;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值