leetcode 198. House Robber

来源:互联网 发布:游戏秀 录制软件 编辑:程序博客网 时间:2024/06/05 14:20

题目描述:

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.

解题思路:

不难看出,这道题是很简单的动态规划问题:

用dp[i]表示以i结尾,所能得到的最大和,可以利用贪心的思想得到状态转移方程为:

dp[i] = max( dp[i-2], dp[i-3] ) + nums[i]

当然,还有另外一种思路:dp[i]表示前i个所能组合得到的最大和,dp[i] = max( dp[i-1], dp[i-2]+nums[i] )

所以可以得到初步的代码如下:

class Solution {public:    int rob(vector<int>& nums) {        if(nums.size() == 0)            return 0;        long long dp[nums.size()+1];        memset(dp, 0, sizeof(dp));        dp[0] = 0;        dp[1] = nums[0];        for(int i = 2; i <= nums.size(); i++){            long long mx;            if(i == 2)                mx = dp[i-2];            else                mx = max(dp[i-2], dp[i-3]);            dp[i] = mx + nums[i-1];        }        return max(dp[nums.size()], dp[nums.size()-1]);    }};

该解法的时间复杂度为O(n),空间复杂度为O(n)。

从上面的分析也不难看出,空间复杂度实际上可以降低到O(1)的,因为实际上真正用到的只有当前值和它临近的两个dp值,所以不需要开辟一个数组的大小,问题的重点就转换为如何优雅地利用这这一点来写代码,下面是我看过的比较简洁的做法(用的是第二种dp思路):

class Solution {public:    int rob(vector<int>& nums) {        long long x = 0, y = 0;        for(int i = 0; i < nums.size(); i++){            int cur = max(y, x+nums[i]);            x = y;            y = cur;        }        return y;    }};



1 0
原创粉丝点击