[LeetCode] House Robber II

House Robber II

Note: This is an extension of House Robber.

After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.

解题思路:

这个是偷东西的升级版。偷东西1版是一条街上一排房子,每个房子里面有金钱若干,其警报系统很怪,只有触发相邻的两个房间,警报系统才发出警报。问如何偷才能得到最大的值。

这个升级版就是这条街不再是一字排开,而是一个环形街,第一个房子与最后一个房子相邻。问如何偷才能得到最大值?

最初的想法是,记录第一个房间是否被偷了,若被偷了,那么最后一个房间就不能偷。然后分情况讨论。但是如何记录第一个房间被偷了呢?似乎比较麻烦。

其实可以有双向扫描法,第一次从左向右扫描,采用动态规划,若d[len-2]==d[len-1],说明最后一个房间我们并没有偷,这种情况跟线性街道是一样的,返回d[len-1]即可,若不相等,说明线性街道时,最后一个房间需要偷,但是我们并不知道第一个房间是否偷了,因此我们还需要扫描一次,从左往右扫描,同样采用动态规划,得出dr[]。

此时有两个动态规划数组d[]和dr[],注意d[]中d[len-1]!=d[len-2]。我们不知道第一间房是否偷了。假如第一间房间偷了,最后一间房不能偷,那么我们返回d[len-2]。假如第一间房没有偷,我们返回dr[1],而不管最后一间房是否被偷。因此,我们只需要返回dr[1]和d[len-2]的较大值即可。

代码比较好懂,发现自己越解释越难懂,唉~ps,leetCode计时坏了吗?为何我的代码跑出来只需0ms?

class Solution {
public:
    int rob(vector<int>& nums) {
        int len = nums.size();
        if(len == 0){
            return 0;
        }
        if(len == 1){
            return nums[0];
        }
        if(len == 2){
            return max(nums[0], nums[1]);
        }
        int d[len];
        d[0]=nums[0];
        d[1]=max(nums[0], nums[1]);
        for(int i=2; i<len; i++){
            d[i]=max(d[i-1], nums[i]+d[i-2]);
        }
        if(d[len-1]==d[len-2]){ //表明最后一家没有偷,跟线性的一样
            return d[len-1];
        }
        //反向扫描
        int dr[len];
        dr[len-1]=nums[len-1];
        dr[len-2]=max(nums[len-1], nums[len-2]);
        for(int i=len-3; i>=0; i--){
            dr[i]=max(dr[i+1], nums[i]+dr[i+2]);
        }
        return max(dr[1], d[len-2]);
    }
};


0 条评论

    发表评论

    电子邮件地址不会被公开。 必填项已用 * 标注