难度:medium
这道题是LeetCode.198. 打家劫舍 的升级版;
因为成了环的缘故要分类讨论取最大值:
-
包括首元素不包括尾元素的区间
-
不包括首元素包括尾元素的区间
Java:
动态规划:
class Solution {
public int rob(int[] nums) {
int length = nums.length;
//特殊情况处理
if (length == 0) {
return 0;
}
if (length == 1) {
return nums[0];
}
if (length == 2) {
return Math.max(nums[0], nums[1]);
}
//两种情况讨论,包括首元素不包括尾元素的区间和不包括首元素包括尾元素的区间
int case1 = robmoney(nums, 0, length - 2);
int case2 = robmoney(nums, 1, length - 1);
return Math.max(case1, case2);
}
public int robmoney(int[] nums, int start, int end) {
int len = end - start + 1;
//dp[i]前i号房能够偷窃到的最高金额
int[] dp = new int[len + 1];
//初始化
dp[start] = nums[start];
dp[start + 1] = Math.max(nums[start], nums[start + 1]);
// 递推方程:dp[i] = Math.max(dp[i - 1], dp[i - 2] +nums[i])
for (int i = start + 2; i <= end; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[end];
// //这个也可以通过
// //初始化
// dp[0] = nums[start];
// dp[1] = Math.max(nums[start], nums[start + 1]);
// // 递推方程:dp[i] = Math.max(dp[i - 1], dp[i - 2] +nums[i])
// for (int i = 2; i <= end - start; i++) {
// dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[start + i]);
// }
// return dp[end - start];
}
}
复杂度分析:
- 时间复杂度:O(n)
- 空间复杂度:O(n)