[LeetCode] House Robber II 求循环数组中元素两两不相邻的子序列最大和

声明:原题目转载自LeetCode,解答部分为原创

Problem :

    Note: This is an extension of House Robber. [LeetCode] 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.

Solution:
    思路:按照题意,给定一个首尾相连的循环数组array[ length ],要求的是满足“元素两两不相邻”的子序列的最大和。由上一道题,我们可以得出一个array[ ]数组中的“满足两两不相邻”条件的子序列的最大和。考虑本题的特殊之处在于“首间房子跟尾间房子不能同时抢劫”,可能有以下三种情况:
    (1)目标子序列不包含array[ ]数组的第一个元素,但包含最后一个元素,结果等价于array[ 1, length - 1 ]在线性数组情景下的返回值;
    (2)目标子序列不包含array[ ]数组的最后一个元素,但包含第一个元素,结果等价于array[ 0, length - 2 ]在线性数组情景下的返回值;
    (3)目标子序列既不包含数组的第一个元素,也不包含最后一个元素,结果等价于array[ 1, length - 1] 和array[ 0, length - 2 ]的相同返回值;
    则调用两次线性数组情景下的函数,返回其中较大的值。代码如下:
class Solution {  
public:  
    int rob(vector& nums) {
        if(nums.size() == 0)
            return 0;  
        if(nums.size() == 1)  
            return nums[0];  
        if(nums.size() == 2)  
            return max(nums[0], nums[1]);  
        if(nums.size() == 3)  
            return max( max(nums[0], nums[1]), nums[2]); 
        
        vector temp_1(nums.size() - 1);
        vector temp_2(nums.size() - 1);
        temp_1.assign(nums.begin(), nums.end() - 1);
        temp_2.assign(nums.begin() + 1, nums.end());
        
        int result_1 = find_max_money(temp_1);
        int result_2 = find_max_money(temp_2);
        return max(result_1, result_2);
    }
    
private:
    int find_max_money(vector &array)
    {
        vector max_money(array.size());  
        max_money[0] = array[0];  
        max_money[1] = array[1];  
        max_money[2] = max(array[0] + array[2], array[1]);  
        int result = max( max(max_money[0], max_money[1]), max_money[2] );  
        for(int i = 3; i < array.size(); i ++)  
        {  
            max_money[i] = array[i] + max(max_money[i - 2], max_money[i - 3]);  
            result = max(result, max_money[i]);  
        }  
        return result; 
    }
};  



你可能感兴趣的:(LeetCode)