Leetcode213题 打家劫舍 II C++解法

先上笨蛋解法,环形偷的关键在于nums[0]和nums[n-1]不会同时被访问,所以设置两个数组,一个从头偷,一个从尾偷。最终比较从头偷还是从尾偷的数大。

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.empty())
        return 0;
        if(nums.size()==1)
        return nums[0];
        int n=nums.size();
        vector<int> dp_l(n+1,0);
        vector<int> dp_r(n+1,0);
        dp_l[1]=nums[0];
        dp_r[n-1]=nums[n-1];
        for(int i=2;i<n;++i)
            {dp_l[i]=max(dp_l[i-1],dp_l[i-2]+nums[i-1]);
            dp_r[n-i]=max(dp_r[n-i+1],dp_r[n-i+2]+nums[n-i]);}       
        return max(dp_l[n-1],dp_r[1]);
    }
};

然而看了答案,好吧,也是这种解法,遍历两遍。
中间我还想过比较nums[0]和nums[n-1],谁大就从哪边偷,但是一个很简单的问题就是两个一样大,就没法了。
答案还是有值得学习的地方的。实际上遍历的操作一样,所以可以写一个遍历函数,省去相同的步骤。以及状态空间可以进一步压缩下。
事实证明,我确实是个自作聪明的大傻X.
还专门把数组反转了下。但是实际上只要一个从0-n-2,一个从2-n-1不就可以了。真的是蠢啊。

class Solution {
public:
    int myRob(vector<int>& nums,int start,int finish)
    {
        int res=nums[start],next_1=nums[start],next_2=0;
        for(int i=start+1;i<finish;++i)
        {
            res=max(next_1,next_2+nums[i]);
            next_2=next_1;
            next_1=res;
        }
        return res;
    }
    int rob(vector<int>& nums) {
        if(nums.empty())
        return 0;
        int res,n=nums.size();
        res=myRob(nums,0,n-1);
        reverse(nums.begin(),nums.end());
        return max(res,myRob(nums,0,n-1));  
    }
};

但是这样的话,就需要加一个size==1的情况

class Solution {
public:
    int myRob(vector<int>& nums,int start,int finish)
    {
        int res=nums[start],next_1=nums[start],next_2=0;
        for(int i=start+1;i<finish;++i)
        {
            res=max(next_1,next_2+nums[i]);
            next_2=next_1;
            next_1=res;
        }
        return res;
    }
    int rob(vector<int>& nums) {
        if(nums.empty())
        return 0;
        if (nums.size()==1)
        return nums[0];
        return max(myRob(nums,0,nums.size()-1),myRob(nums,1,nums.size()));  
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值