198.打家劫舍
解题思路:
动态规划+滚动数组
package leadcode;
/**
* @author : icehill
* @description : 打家劫舍
* 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
* 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
* 示例 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 。
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/house-robber
* 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
* 解题思路:
* 分析过程
* 每间房屋都可能被偷,具体取决于房屋的金额,那么如果使得偷到的金额最大呢?
* 我们来分析下:用a1 a2比喻房子,s代表偷k间房子的最大金额
* 1.只有1间房子
* 偷或不偷:s1=a1
* 2.2间房子
* 偷1或者偷2==a2偷或不偷:s2=max(a2,s1)(不偷等价于偷1间房子的情况)
* 3.3间房子
* 偷1+3或者偷2==a3偷或不偷:s3=max(s1+a3,s2)
* 4.4间房子(每多一间房子,就需要在前面的情况下增加该房子偷或不偷的情况)
* 偷4或者不偷:s4=max(s2+a4,s3)
* 隐藏的两个条件是本题动态规划解题的关键:
* 1.ak偷的话,a(k-1)不能偷,当前最大值为s(k-2)+ak
* 2.ak不偷的话,相当于没有ak,那就是s(k-1)了
* 所以综上分析,需要找出递推公式才能求解改题
* sk=max(s(k-2)+ak, s(k-1)) 也就是sk最大值是多少依赖于欠s(k-1) 跟s(k-2)
* 时间复杂度:O(n) 空间复杂度:O(1)
* @date : 2021-05-03
*/
public class Solution198 {
public static void main(String[] args) {
Solution198 solution198 = new Solution198();
int[] nums1 = {2, 7, 9, 3, 1};
System.out.println(solution198.rob(nums1));
}
public int rob(int[] nums) {
int max = 0;
int prePre = 0;
int pre = 0;
for (int i = 0; i < nums.length; i++) {
max = Math.max(prePre + nums[i], pre);
prePre = pre;
pre = max;
}
return max;
}
}