打家劫舍系列
系列题区别在于:
- 打家劫舍Ⅰ:线性数组dp
- 打家劫舍Ⅱ:环形数组dp
- 打家劫舍Ⅲ:(二叉)树型dp
打家劫舍Ⅱ
问题其实只会发生在最后一户,如果第一户被偷了,那它就不能被偷
那我循环每一户作为开始节点…
线性dp只能考虑它前面的步骤,否则就不成立…
好,我看到提示了,提示的意思是
- 第一户被偷了,第n户不能被偷,就是dp[n-1]
- 第一户没被偷,第n户可以被偷,就是dp[2]-dp[n]
那…考虑能不能一次遍历,好像不太行,单独抽一个方法出来
第一次提交没考虑到一个问题,当数组长度只有1的时候,robrob(nums, 1, n )
这里的调用会发生越界
int robrob(vector<int>& nums,int i,int j) {
int prepre = 0, pre = nums[i], cur = nums[i];
for (int k = i + 1; k < j; k++) {
cur = max(prepre + nums[k], pre);
prepre = pre;
pre = cur;
}
return cur;
}
int rob(vector<int>& nums) {
int n = nums.size();
if(n==1) return nums[0];
return max(robrob(nums, 0, n - 1), robrob(nums, 1, n ));
}
好吧,思路看起来没有问题,但毕竟不是自己想出来的,总有点存疑,另外,感觉这个写法太直接了,时间复杂度O(2N)
,有没有更巧妙地优化写法?