leetcode House Robber I II

House Robber

题目

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

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

分析

题目的要求是在一条街上有一系列的房子,每个房子有固定的资产,一个强盗抢劫这条街上的房子,唯一的要求是不能抢劫两个相邻的房子,因为为导致报警。
这一系列的房子资产就是一个数组。
我们可以用一个结果数组来表示到当前这个房子,可以获得的最多资产。
现在,列出状态转移方程如下:

result[i] = max(result[i - 1], result[i - 2] + nums[i];

状态的初始化如下:

vector<int> result;
result.push_back(nums[0]);
if (nums[1] < nums[0]) result.push_back(nums[0]);
else result.push_back(nums[1]);

代码:

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

运行结果

这里写图片描述

对空间复杂度的改进

通过对以上代码的分析,可以看到,每一个result[i]只用到了result[i - 1] 和 result[i - 2],因此,完全可以只用两个变量来实现,将空间复杂度从O(n) 降到 O(1)。
代码如下:

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 0) return 0;
        if (nums.size() == 1) return nums[0];
        int a = 0, b = 0;
        for (int i = 0 i < nums.size(); i++) {
            if (i % 2 == 0) {
                a = max(a + nums[i], b);
            } else {
                b = max(a, b + nums[i]);
            }
        }
        return max(a, b);
    }
};

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.

分析

与House Robber I比较,添加的要求是,这条街道是一个环,即第一个房子和最后一个房子也是相邻的。也即对结果加以限制。
可以沿用第一题的思路,将nums数组分成两个,一个将第一个房子去掉,一个将最后一个房子去掉。最后的抢劫最大资产最多也只能抢劫第一个房子或者最后一个房子。
状态转移方程与上面相同,只是,分成了两个数组,也即分别对两个数组应用状态转移方程求最大值。然后再去两个数组的最大值的最大值。

代码

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

结果

这里写图片描述

改进

同样可以对空间复杂度进行优化,与上一题相似,不再赘述。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值