@author: sdubrz
@date: 2020.04.16
题号: 198
题目难度: 简单
考察内容: 动态规划
原题链接 https://leetcode-cn.com/problems/house-robber/
题目的著作权归领扣网络所有,商业转载请联系官方授权,非商业转载请注明出处。
解题代码转载请联系 lwyz521604#163.com
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 1:
输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
通过次数100,127提交次数226,125
解法
记 money(i)
为子数组 nums[1...n]
的最优解。则 money(1)=nums[1]
, money(2)=max{nums[1], nums[2]}
。 对于给定的一个 n
,如果我们已知 money(i)
, i<n
,那么对于当前的第 n
个元素,有两种可能的操作:
- 偷
nums[n]
,则一定不能偷nums[n-1]
。在这种情况下最大的收益为money(n-2)+nums[n]
。 - 不偷
nums[n]
。这种情况下,最大的收益为money(n-1)
。
则最终的 money(n)
就是以上两种中的较大者。下面是具体的实现代码:
class Solution {
public int rob(int[] nums) {
if(nums.length==0){
return 0;
}
if(nums.length==1){
return nums[0];
}
int[] money = new int[nums.length];
money[0] = nums[0];
money[1] = Math.max(nums[0], nums[1]);
for(int i=2; i<money.length; i++){
money[i] = Math.max(money[i-1], money[i-2]+nums[i]);
}
return money[money.length-1];
}
}
在 LeetCode 系统中的提交结果如下
执行结果: 通过 显示详情
执行用时 : 0 ms, 在所有 Java 提交中击败了 100.00% 的用户
内存消耗 : 36.9 MB, 在所有 Java 提交中击败了 6.52% 的用户