[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<int>& 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<int> temp_1(nums.size() - 1);
        vector<int> 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<int> &array)
    {
        vector<int> 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; 
    }
};  



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值