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.
动态优化
第一反应就是用动态优化写。注意题目要求,即不能连续抢夺两间屋子的钱财,即不能连续读取相邻的两个数。
数组没有内容时显然答案是0,数组只有一个数据时显然答案就是第一个数字,数组只有两个数据时显然答案是最大数。
当数组内容大于3时开始DP,每次要进行是把第 i 个数字(i > 3)读入的情况。
若添加,则显然第 i - 1 个数字无法添加,总金额就是第 i - 2 间屋子时的所得总金额加上第 i 间屋子的金额。
若跳过,则总金额就是第 i - 1 间屋子时的所得总金额。
代码如下:
public class Solution {
public int rob(int[] nums) {
if(nums.length == 0) return 0;
if(nums.length == 1) return nums[0];
if(nums.length == 2) return Math.max(nums[0], nums[1]);
int [] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for(int i = 2; i < nums.length; i++) {
dp[i] = Math.max(dp[i-2] + nums[i], dp[i - 1]);
}
return dp[nums.length-1];
}
}
若对数组进行空间优化,则每次 dp 位置为 i 对 2 取模。优化后代码如下:
public class Solution {
public int rob(int[] nums) {
if(nums.length == 0) return 0;
if(nums.length == 1) return nums[0];
if(nums.length == 2) return Math.max(nums[0], nums[1]);
int [] dp = new int[2];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for(int i = 2; i < nums.length; i++) {
int temp = i % 2;
dp[temp] = Math.max(dp[temp] + nums[i], dp[temp^1]);
}
return Math.max(dp[0], dp[1]);
}
}
有个小问题,改了几次一直维持在 1ms,同样的算法在运算时间上总是比别人差,不知道哪里还能优化,欢迎指教。