Description:
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.
Example 1:
Input: [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
Example 2:
Input: [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.
题意:用一个一维数组表示每个房子里面钱的金额,计算一个小偷所能够偷到的钱的最大值,要求不可以偷取两个相邻的房子;
解法:假如给定的数组为house = {m1, m2, m3,…, mn},计算的函数为robMax(house, pos),对于每一个房子都有两种可能(偷或者不偷),那么我们考虑第一栋房子
- 如果偷的话,那么偷取的最大金额应当是house[0] + robMax(house, 0 + 2);
- 如果不偷的话,那么偷取的最大金额应当是robMax(house, 0 + 1);
我们只需要比较哪种情况下偷取的金额最大即可;同理,可求解其他位置的情况;
这种方法最后的结果会产生超时,考虑动态规划的方法,将计算过的中间结果存储下来;为了处理方便,这里我采用了逆序遍历房子;
Java
class Solution {
public int rob(int[] nums) {
int[] table = new int[nums.length];
for (int i = 0; i < table.length; i++) {
table[i] = -1;
}
return robMax(nums, nums.length - 1, 0, table);
}
private int robMax(int[] nums, int pos, int money, int[] table) {
if (pos < 0) {
return 0;
}
int money1 = 0;
int money2 = 0;
if (pos - 2 >= 0 && table[pos - 2] >= 0) {
money1 += table[pos - 2];
} else {
money1 += robMax(nums, pos - 2, money, table);
}
if (pos - 1 >= 0 && table[pos - 1] >= 0) {
money2 += table[pos - 1];
} else {
money2 += robMax(nums, pos - 1, money, table);
}
money += Math.max(money1 + nums[pos], money2);
table[pos] = money;
return money;
}
}