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