LeetCode213. 打家劫舍 II

111 阅读1分钟

LeetCode213. 打家劫舍 II

 # 你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。
 ​
 给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。
 ​
  
 ​
 示例 1:
 ​
 输入:nums = [2,3,2]
 输出:3
 解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。
 示例 2:
 ​
 输入:nums = [1,2,3,1]
 输出:4
 解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。
      偷窃到的最高金额 = 1 + 3 = 4 。
 示例 3:
 ​
 输入:nums = [1,2,3]
 输出:3
  
 ​
 提示:
 ​
 1 <= nums.length <= 100
 0 <= nums[i] <= 1000

解题思路

打家劫舍II 分成两个 打家劫舍I 去做:

n 个房间,编号为 0...n - 1,分成两种情况:

  1. 偷编号为 0...n - 2n - 1 个房间;
  2. 偷编号为 1...n - 1n - 1 个房间;

最后的结果是二者的最大值~

代码

 public int rob(int[] nums) {
 ​
         int len = nums.length;
 ​
         if (len == 0) return 0;
         if (len == 1) return nums[0];
         if (len == 2) return Math.max(nums[0], nums[1]);
 ​
 ​
         return Math.max(dp(nums, 0, len - 2), dp(nums, 1, len - 1));
 ​
     }
 ​
     public int dp(int[] nums, int s, int e){
         int first = nums[s], second = Math.max(nums[s], nums[s + 1]);
         for (int i = s + 2; i <= e; i++) {
             int temp = second;
             second = Math.max(second, nums[i] + first);
             first = temp;
         }
         return second;
     }

运行结果

image.png