198.打家劫舍
要点:1. 房子形状为数组,dp[i] 偷到第 i 间房子,最多可以偷多少;2. 递推公式,由前两间房子被偷的状态推导出来;3. 初始化,i 与 i-1 i-2 有关,所以初始化 0 1;4. 顺序,i 与 i-1 i-2 有关,所以正序
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.size() == 1)
return nums[0];
vector<int> dp(nums.size(), 0);
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
for (int i = 2; i < nums.size(); i++) {
dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
}
return dp[nums.size() - 1];
}
};
213.打家劫舍II
要点:房子形状为环,所以分两种,头不偷、尾不偷,两种情况取最大
class Solution {
public:
int robIndex(vector<int>& nums, int start, int end) {
vector<int> dp(nums.size() - 1, 0);
dp[0] = nums[start];
dp[1] = max(nums[start], nums[start + 1]);
for (int i = 2; i < nums.size() - 1; i++) {
dp[i] = max(dp[i - 2] + nums[start + i], dp[i - 1]);
}
return dp[nums.size() - 2];
}
int rob(vector<int>& nums) {
if (nums.size() == 1)
return nums[0];
if (nums.size() == 2)
return max(nums[0], nums[1]);
int result1 = robIndex(nums, 0, nums.size() - 2);
int result2 = robIndex(nums, 1, nums.size() - 1);
return max(result1, result2);
}
};
337.打家劫舍III
要点:房子形状为树,需要后序遍历,看代码吧
class Solution {
public:
vector<int> robTree(TreeNode* cur) {
if (cur == nullptr)
return vector<int>{0, 0};
vector<int> left = robTree(cur->left);
vector<int> right = robTree(cur->right);
int val1 = cur->val + left[0] + right[0];
int val2 = max(left[0], left[1]) + max(right[0], right[1]);
return {val2, val1};
}
int rob(TreeNode* root) {
vector<int> result = robTree(root);
return max(result[0], result[1]);
}
};