LeetCode213: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.

续接前面的House Robber I 但是想了好久都没想出来怎么解。加上条件的DP问题需要进行一定的转化才能成为标准的DP问题,这个转化就成了关键。

这里的关键就是最后那一个房间N和第一个房间相连了,可以这么进行转化:

考虑抢劫了第0个房间,那么问题就是求抢劫第0~N-1个房间的最大数。

考虑不抢劫第0个房间,那么问题就是求抢劫第1~N个房间的最大数。

上面转化后的两个问题就是House Robber I中的问题。再求上面两个解的最大值,就是本题的解。

在做这题时发现House Robber I中的代码还可以进一步的优化,可以将数组也省略掉而只使用两个变量来存储值,这样空间复杂度也降到了O(1)。代码更优了。

 这是因为House Robber I只需要比较第A[i-2]+nums[i]和A[i-1]的大小,所以可以把House Robber I中的数组也省略掉,而只需要两个变量来存储着两个值,这样更能节约空间。这里pLast存储的是House Robber I中A[i-1]的值,ppLast存储的是House Robber I中A[i-2]的值,逻辑和House Robber I是一样的。

runtime:0ms

class Solution {
public:
    int rob(vector<int>& nums) {
        int length=nums.size();
        if(length==0)
            return 0;
        if(length==1)
            return nums[0];
            
        return max(robDiv(nums,0,length-2),robDiv(nums,1,length-1));
    }
    
    int robDiv(vector<int> &nums,int first,int last)
    {
        //因为只需要比较第A[i-2]+nums[i]和A[i-1]的大小,所以可以把House Robber I中的数组也省略掉,
        //而只需要两个变量来存储着两个值,这样更能节约空间。
        //这里pLast存储的是House Robber I中A[i-1]的值,
        //ppLast存储的是House Robber I中A[i-2]的值,逻辑和House Robber I是一样的。
        int pLast=0,ppLast=0;
        for(int i=first;i<=last;i++)
        {
            int tmp=pLast;
            pLast=max(ppLast+nums[i],pLast);
            ppLast=tmp;
        }
        return pLast;
    }
};



你可能感兴趣的:(LeetCode213:House Robber II)