打家劫舍 II
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 20 ms, 内存: 16.1 MB
/*
题目思路:
1. 由于房屋围成一圈,不能同时偷第一个和最后一个房屋。
2. 分为两种情况:
a. 偷第一间,不偷最后一间。
b. 不偷第一间,偷最后一间。
3. 分别计算这两种情况下的最大偷窃金额,取两者最大值。
4. 可以复用之前House Robber问题的解决方案,使用动态规划来解决。*/
import java.util.Arrays;
import java.util.stream.IntStream;
public class Solution {
public int rob(int[] nums) {
if (nums.length == 1) return nums[0];
return Math.max(robLinear(Arrays.copyOfRange(nums, 0, nums.length - 1)),
robLinear(Arrays.copyOfRange(nums, 1, nums.length)));
}
private int robLinear(int[] nums) {
int[] result = {0, 0};
IntStream.of(nums).forEach(num -> {
int temp = result[1];
result[1] = Math.max(result[0] + num, result[1]);
result[0] = temp;
});
return result[1];
}
}
解释
方法:
此问题是经典的打家劫舍问题的变种,其中房屋是环形排列的。由于第一个和最后一个房屋相邻,不能同时偷窃,因此问题可以分解为两个子问题:1)偷窃第一间到倒数第二间房屋的最大金额;2)偷窃第二间到最后一间房屋的最大金额。通过解决这两个子问题,取二者的最大值即可得到整个问题的解。内部函数rob处理的是标准的线性房屋排列的打家劫舍问题,使用动态规划的思想,其中cur表示当前房屋的最大偷窃金额,pre表示前一间房屋的最大偷窃金额。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在解决环形房屋偷窃问题时,分解成两个子问题(偷窃第一间到倒数第二间和偷窃第二间到最后一间)的方法是否总是有效?是否存在特殊情况下这种方法会出现问题?
▷🦆
函数rob中使用了动态规划的方法,其中`cur, pre = max(pre + num, cur), cur`这行代码的具体逻辑是什么?能否详细解释这个状态转移方程?
▷🦆
在给定的解法中,对于只有一间或没有房屋的特殊情况已经进行了处理。对于只有两间房屋的情况,这种方法处理的结果是正确的吗?如何验证?
▷