• 代码随想录二刷 Day50


    198.打家劫舍 

    这个题一开始由于给出来的例子陷入了思维误区,以为结果就是每隔一个取一个,其实有可能中间隔很多个。比如一下这个例子

    下面这种写法不对。

    1. class Solution {
    2. public:
    3. int rob(vector<int>& nums) {
    4. int odd_sum = 0;
    5. int even_sum = 0;
    6. for( int i = 0; i < nums.size(); i = i + 2){
    7. odd_sum += nums[i];
    8. }
    9. for( int j = 1; j < nums.size(); j = j + 2){
    10. even_sum += nums[j];
    11. }
    12. return max(odd_sum, even_sum);
    13. }
    14. };

    下面这种动态规划才能做出来;

    1. class Solution {
    2. public:
    3. int rob(vector<int>& nums) {
    4. if (nums.size() == 0) return 0;
    5. if (nums.size() == 1) return nums[0];
    6. vector<int> dp(nums.size() + 1, 0); //dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。
    7. dp[0] = nums[0];
    8. dp[1] = max (nums[0], nums[1]);
    9. for (int i = 2; i < nums.size(); i++) {
    10. dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);
    11. }
    12. return dp[nums.size() - 1];
    13. }
    14. };

    213.打家劫舍II

    情况二就是假设不存在最后一个元素来求最大可以偷的, 情况上就是假设不存在第一个元素来求最大可以偷的,具体情况二选不选择首元素这个要看递推公式来决定;

    1. class Solution {
    2. public:
    3. int rob(vector<int>& nums) {
    4. if (nums.size() == 0) return 0;
    5. if (nums.size() == 1) return nums[0];
    6. int result_1 = robRange(nums, 0, nums.size() - 2);
    7. int result_2 = robRange(nums, 1, nums.size() - 1);
    8. return max(result_1, result_2);
    9. }
    10. int robRange(vector<int>& nums, int start, int end) {
    11. if (end == start) return nums[start]; //这行不写会报错越界之类的
    12. vector<int> dp(nums.size(), 0);
    13. dp[start] = nums[start];
    14. dp[start + 1] = max(nums[start], nums[start + 1]);
    15. for (int i = start + 2; i <= end; i++) {
    16. dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);
    17. }
    18. return dp[end];
    19. }
    20. };

    337.打家劫舍 III

    树形dp,后序遍历。挺难的做不出; dp的含义是dp[0]是不屈这个current的最大值,dp[1]是取这哦current的最大值

    1. class Solution {
    2. public:
    3. int rob(TreeNode* root) {
    4. vector<int> result = robTree(root);
    5. return max(result[0], result[1]);
    6. }
    7. // 长度为2的数组,0:不偷,1:偷
    8. vector<int> robTree(TreeNode* cur) {
    9. if (cur == NULL) return vector<int>{0, 0};
    10. vector<int> left = robTree(cur->left);
    11. vector<int> right = robTree(cur->right);
    12. // 偷cur,那么就不能偷左右节点。
    13. int val1 = cur->val + left[0] + right[0];
    14. // 不偷cur,那么可以偷也可以不偷左右节点,则取较大的情况
    15. int val2 = max(left[0], left[1]) + max(right[0], right[1]);
    16. return {val2, val1};
    17. }
    18. };

  • 相关阅读:
    计算机竞赛 基于深度学习的动物识别 - 卷积神经网络 机器视觉 图像识别
    IDEA运行main方法,为什么要编译整个工程?
    一体化运维监控:提供全方位数据洞察
    CKA考试笔记,仅做个人学习使用
    过滤器、监听器、拦截器的区别,你都搞懂了吗?
    华为ce12800交换机m-lag(V-STP模式)配置举例
    RxJava 异常时堆栈显示不正确?解决方法都在这里
    一个漏测Bug能让你想到多少?
    关于el-date-picker点击清空参数变为null的问题
    用python解决Excel 表中某个范围内的单元格
  • 原文地址:https://blog.csdn.net/weixin_43908951/article/details/134025707