力扣198. 打家劫舍

198. 打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 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

提示:
0 <= nums.length <= 100
0 <= nums[i] <= 400

思路一:

回溯法:

 1 class Solution {
 2     public int rob(int[] nums) {
 3         // 回溯法,每个屋子都可以选择偷和不偷,如果选择偷的话下标加2,如果不偷的话下标加一
 4         robHelper(nums, 0, 0);
 5         return maxHarvest;
 6     }
 7 
 8     public int maxHarvest = 0;
 9 
10     public void robHelper(int[] nums, int nowIndex, int nowSum){
11         // 跳出条件
12         if(nowIndex >= nums.length){
13             if(maxHarvest < nowSum){
14                 maxHarvest = nowSum;
15             }
16             return;
17         }
18 
19         // 选择不偷
20         robHelper(nums, nowIndex + 1, nowSum);
21 
22         // 选择偷
23         robHelper(nums, nowIndex + 2, nowSum + nums[nowIndex]);
24     }
25 }

力扣测试:超时

 复杂度分析:

时间复杂度:每间屋子都可以选择偷与不偷,所以时间复杂度为O(2^n)

空间复杂度:递归层数最大为n层(即当所有屋子都选择不偷时),所以空间复杂度为O(n)

思路二:动态规划

dp[i] = Math.max(dp[i-1], dp[i-2] + num);

 1 class Solution {
 2     public int rob(int[] nums) {
 3         // 动态规划
 4         // dp[i] = Math.max(dp[i-1], dp[i-2] + num)
 5         if(nums == null || nums.length == 0){
 6             return 0;
 7         }
 8 
 9         int n = nums.length;
10         if(n == 1){
11             return nums[0];
12         }
13         int[] dp = new int[n];
14         dp[0] = nums[0];
15         dp[1] = Math.max(nums[0], nums[1]);
16         for(int i = 2; i < n; i++){
17             dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
18         }
19        return dp[n-1];
20     }
21 }

力扣测试时间为0ms, 空间为37.1MB

复杂度分析:

时间复杂度和空间复杂度都是O(n)

不使用额外空间的动态规划

 1 class Solution {
 2     public int rob(int[] nums) {
 3         // 动态规划
 4         // dp[i] = Math.max(dp[i-1], dp[i-2] + num)
 5         if(nums == null || nums.length == 0){
 6             return 0;
 7         }
 8 
 9         int n = nums.length;
10         if(n == 1){
11             return nums[0];
12         }
13         nums[1] = Math.max(nums[0], nums[1]);
14         for(int i = 2; i < n; i++){
15             nums[i] = Math.max(nums[i-1], nums[i-2] + nums[i]);
16         }
17        return nums[n-1];
18     }
19 }

力扣测试时间为0ms,空间为37MB

复杂度分析:

时间复杂度为O(n)

空间复杂度为O(1)

思路参考:

https://leetcode-cn.com/problems/house-robber/solution/da-jia-jie-she-by-leetcode-solution/

原文地址:https://www.cnblogs.com/hi3254014978/p/13170334.html