198.打家劫舍 (中等)
leetcode题目链接:198. 打家劫舍 - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)
视频讲解:动态规划,偷不偷这个房间呢?| LeetCode:198.打家劫舍_哔哩哔哩_bilibili
题目描述
解题思路
对于第i家,有两种情况 :1.偷第i家。2.不偷第i家。那么偷不偷第二家其实和前两家有关。
如果偷了第i-2家,那么第i家就可以偷,如果偷了第i-1家,那么第i家就不能偷。
那么我们可以用动态规划的思路来解决这个问题。
1.dp数组及下标含义
dp[i]表示到第i家时,偷窃到的最大金额dp[i]。
2.递推公式
如果偷第i-2家,那dp[i] = dp[i-2] + nums[i]
如果偷第i-1家,那么dp[i] = dp[i-1]
故dp[i] = max(dp[i-1] , dp[i-2]+nums[i])
3.初始化
dp[0] = 0。
dp[1] = max (nums[0],nums[1])。
4.遍历顺序
从前往后偷。
题目代码
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size()==0)
return 0;
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(中等)
leetcode题目链接:213. 打家劫舍 II - 力扣(LeetCode)
文章讲解:代码随想录 (programmercarl.com)
视频讲解:动态规划,房间连成环了那还偷不偷呢?| LeetCode:213.打家劫舍II_哔哩哔哩_bilibili
题目描述
解题思路
本题和上一题不同的情况就在于首位两个元素选不选的情况。
那么我们可以分成三种情况:
1.首位元素都不考虑,只考虑中间元素。
2.首元素考虑,尾元素不考虑。
3.首元素不考虑,尾元素考虑。
上面三种情况也就成了打家劫舍1的题,而对于情况1,在2和3中以及包含。故返回一个2 ,3最大值即可。
题目代码
class Solution {
public:
int rob(vector<int>& nums) {
if (nums.size() == 0)
return 0;
if (nums.size() == 1)
return nums[0];
int case1 = robb(nums, 0, nums.size() - 2);
int case2 = robb(nums,1,nums.size()-1);
return max(case1, case2);
}
private:
int robb(vector<int>& n_nums,int begin,int end) {
if (end == begin) return n_nums[begin];
vector<int>nums(n_nums.begin()+begin, n_nums.begin()+end+1);
vector<int> dp(nums.size());
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];
}
};
337.打家劫舍 III(中等)
题目代码
class Solution{
public:
int rob(TreeNode * root) {
vector<int> result = robTree(root);
return max(result[0], result[1]);
}
vector<int> robTree(TreeNode* cur)
{
if (cur == nullptr)
return { 0,0 };
vector<int>left = robTree(cur->left);
vector<int>right = robTree(cur->right);
//偷cur
int val1 = cur->val + left[0] + right[0];
//不偷cur
int val2 = max(left[0], left[1]) + max(right[0], right[1]);
return { val2,val1 };
}
};