# leetcode 198. House Robber

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.

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.

//leetcode 198. House Robber  自顶向下 记忆化搜索
static int len;
public static int rob(int[] nums) {
len = nums.length;
if(len==0)
return 0;
int[] memo = new int[len];
for(int i=0;i<len;i++)
memo[i] = -1;
return maxRob(nums,0,memo);
}

public static int maxRob(int[] nums,int index,int[] memo){
if(index == len-1){
//System.out.println("memo["+index+"]="+memo[index]);
return nums[index];
}
if(index >= len)
return 0;
if(memo[index] != -1)
return memo[index];
int max=0;
for(int i=index;i<len;i++){
//System.out.println("i="+i+" nums[i]="+nums[i]+" max="+max);
max = Math.max(max, nums[i] + maxRob(nums, i+2,memo));
//System.out.println("i="+i+" nums[i]="+nums[i]+" max="+max);
}
memo[index] = max;
return max;

}


//leetcode 198. House Robber  动态规划  自下向上 考虑偷取 [x...n-1]范围的房子 （函数的定义）
public static int rob2(int[] nums){
int len = nums.length;
if(len==0)
return 0;
int[] memo = new int[len];
memo[len-1] = nums[len-1];
for(int i=len-2;i>=0;i--){
int max = 0;
for(int j=i;j<len;j++){
//考虑到数组越界的问题
max = Math.max(nums[j] +((j+2)>=len ? 0 : memo[j + 2]), max);
//System.out.println("max=" + max);
}
memo[i] = max;
//System.out.println("memo["+i+"]="+memo[i]);
}
return memo[0];
}


//leetcode 198. House Robber  动态规划  自下向上 考虑偷取 [0...x]范围的房子 （函数的定义）
public static int rob3(int[] nums){
int len = nums.length;
if(len==0)
return 0;
int[] memo = new int[len];
//[0...0]范围偷取的最大值为nums[0]
memo[0] = nums[0];
for(int i=1;i<len;i++){
int max = 0;
for(int j=i;j>=0;j--){
max = Math.max(nums[j] +((j-2)<0 ? 0 : memo[j - 2]), max);
//System.out.println("max=" + max);
}
memo[i] = max;
//System.out.println("memo["+i+"]="+memo[i]);
}
return memo[len-1];
}