You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, but adjacent houses have security systems connected — if two adjacent houses are broken into on the same night, the police will be automatically alerted.
Given a list of non-negative integers representing the amount of money in each house, determine the maximum amount you can rob tonight without alerting the police.
Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases, and to @ts for adding additional test cases.
Subscribe to see which companies asked this question.
暴力递归解法
先用暴力递归来求解:
int search(const vector<int>& nums, int index) {
if (index >= nums.size())return 0;
return max(nums[index] + search(nums, index - 2),//偷这家
search(nums, index - 1));//不偷这家
return 0;
}
int rob(const vector<int>& nums) {
return search(nums, nums.size()-1);//2^n
return 0;
}
动态规划解法
暴力递归会超时,原因是大量相同的子问题被重复计算——例如递归到 index=3 时,必然包含了 index=2 的计算。
可以用一个数组缓存每个位置的搜索结果,从而将暴力递归转换为 DP。自底向上按递推式推导下一个状态:状态 0 为 0,状态 1 只能偷取第一家。
int rob(const vector<int>& nums) {
int *arr=new int[nums.size()+10];
memset(arr, 0, (sizeof (int))*(nums.size()+10));
arr[0] = 0;
arr[1] = nums[0];
for (int i = 2; i <= nums.size(); i++)
{
arr[i] = max(nums[i-1] + arr[i - 2], arr[i - 1]);
}
return arr[nums.size()];
return 0;
}