198. House Robber
用滚动数组实现O(1)空间
需要注意的是更新时index的处理
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
vector<int> v(3, 0);
for (int i = 0; i < n; i++) {
if (i == 0) {
// 0 case is diff with 1 case
v[i] = max(0, nums[i]);
} else if (i == 1) {
v[i] = max(v[i-1], nums[i]);
} else {
// pay attention to three indexes
int d = i % 3;
v[d] = max(v[(d+2)%3], v[(d+1)%3] + nums[i]);
}
}
return max(v[0], max(v[1], v[2]));
}
};
213. House Robber II
需要两次遍历,进一步优化了上题的滚动数组,改用两个变量,y代表截止上一个的最大值,x代表截止上上个的最大值
需要注意处理n为1的情况
class Solution {
public:
int robRange(vector<int>& nums, int l, int r) {
if (l > r) return 0;
int n = nums.size();
int x = 0, y = 0;
for (int i = l; i <= r; i ++) {
int temp = max(y, x + nums[i]);
x = y;
y = temp;
}
return max(x, y);
}
int rob(vector<int>& nums) {
int n = nums.size();
if (n == 1) return max(0, nums[0]); // corner case
return max(robRange(nums, 0, n - 2), robRange(nums, 1, n - 1));
}
};
337. House Robber III
树形dp,当前节点max value = max(当前节点value + max(左儿子的子节点) + max(右儿子的子节点),
max(左子树的max value) + max(右子树的max value))
需要注意的是中间都是累加关系,因为左右子树都没有关系可以加起来,不要习惯性写成求max
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int rob(TreeNode* root) {
vector<int> ans = f(root);
return max(ans[0], ans[1]);
}
vector<int> f(TreeNode* r) {
vector<int> ans(2, 0), left, right;
// ans[0]: max sum include current value
// ans[1]: max sum of two sub-tree
if (r == NULL) return ans;
left = f(r->left);
right = f(r->right);
ans[0] = (r->val) + left[1] + right[1];
ans[1] = max(left[0], left[1]) + max(right[0], right[1]); // not max but sum
return ans;
}
};