leetcode House Robber I II

来源:互联网 发布:软件质量管理计划 编辑:程序博客网 时间:2024/06/03 20:12

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]);    }};

结果

这里写图片描述

改进

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

原创粉丝点击