首页 > 其他分享 >代码随想录day48 | 198.打家劫舍 213.打家劫舍II 337.打家劫舍III

代码随想录day48 | 198.打家劫舍 213.打家劫舍II 337.打家劫舍III

时间:2022-11-09 16:23:00浏览次数:75  
标签:return 213 nums int 随想录 vector 打家劫舍 dp size

198.打家劫舍

题目|文章
image

思路

  1. 数组以及下标含义
    dp[j]:当偷到第j家时所能获得的最多的金钱
  2. 递推公式
    dp[j] = max(dp[j - 1], dp[j - 2] + nums[i])
    当偷到第j家时,如果偷这家,那么就不能偷前一家,所能得到的最大金额为dp[j - 2] + prices[i]
    如果不偷这家,获得的金额与偷到第j-1家相等,所获得的最大金额为dp[j-1]。选取两者中的最大值
  3. 初始化
    如果只有一家,那么直接返回该房屋的金额。如果有两家,那么返回两个房屋的大金额。
  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-1], dp[i-2] + nums[i]);
            
        }
        return dp[nums.size()-1];
    }
};

复杂度分析

  • 时间复杂度:O(n),n为数组的长度
  • 空间复杂度:O(n)

213.打家劫舍II

题目|文章
image

思路

这道题与上一道题的区别在于不能同时偷第一家和最后一家,那么只能将两种情况分开讨论。

实现

点击查看代码
class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size() == 1) return nums[0];
        else if(nums.size() == 2) return max(nums[0], nums[1]);

        int result1 = myRob(nums, 0, nums.size() - 2);
        int result2 = myRob(nums, 1, nums.size() - 1);
        return max(result1, result2);        
    }
    int myRob(vector<int>& nums, int start, int end) {
        vector<int> dp(nums.size(), 0);
        dp[start] = nums[start];
        dp[start+1] = max(nums[start], nums[start + 1]);
        for(int i = start + 2; i <= end; i++) {
            dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);
        }
        return dp[end];
    }
};

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

337.打家劫舍III

题目|文章
image

思路

实现

点击查看代码
class Solution {
public:
    int rob(TreeNode* root) {
        vector<int> result = robTree(root);
        return max(result[0], result[1]);
    }
    vector<int> robTree(TreeNode* root) {
        if(root == nullptr) return {0, 0};
        vector<int> left = robTree(root->left);
        vector<int> right = robTree(root->right);
        int val1 = root->val + left[0] + right[0];
        int val2 = max(left[0],left[1]) + max(right[0], right[1]);
        return {val2, val1}; 
    }
};

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(logn)

标签:return,213,nums,int,随想录,vector,打家劫舍,dp,size
From: https://www.cnblogs.com/suodi/p/16874187.html

相关文章