代码随想录算法训练营第四十八天—动态规划009

第一题、打家劫舍 力扣题目链接

class Solution {
public:
    int rob(vector& nums) {
        if(nums.size() == 0) return 0;
        if(nums.size() == 1) return nums[0];
        vector 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];
    }
};

第二题、打家劫舍II 力扣题目链接

与上题逻辑相同,就是把环拆分考虑。考虑头节点和考虑尾节点两种情况,然后逻辑和第一个一样,求得每个逻辑的最大值,然后取最大值即可

class Solution {
public:
    int rob(vector& nums) {
        if(nums.size() == 0) return 0;
        if(nums.size() == 1) return nums[0];
        int result1 = robRange(nums, 0, nums.size() - 2);
        int result2 = robRange(nums, 1, nums.size() - 1);
        return max(result1, result2);
    }
    int robRange(vector& nums, int start, int end){
        if(start == end) return nums[end];
        vector dp(nums.size(), 0);
        dp[start] = nums[start];
        dp[start + 1] = max(nums[start + 1], nums[start]);
        for(int i = start + 2; i <= end; i++){
            dp[i] = max(dp[i-2] + nums[i], dp[i-1]);
        }
        return dp[end];
    }
};

第三题、打家劫舍III 力扣题目链接

class Solution {
public:
    int rob(TreeNode* root) {
        vector result = robTree(root);
        return max(result[0], result[1]);
    }
    vector robTree(TreeNode* root){
        if(root == NULL) return vector{0, 0};
        vector left = robTree(root->left);
        vector 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};  // 返回顺序不能颠倒
    }
};

返回的是当前节点不偷窃和偷窃时的最大收益,所以返回值应该是{val2, val1},不能颠倒顺序。如果颠倒了顺序,那么返回的就是偷窃和不偷窃的收益的顺序,与题目要求不符,会导致错误的结果

你可能感兴趣的:(算法,动态规划,leetcode,数据结构,c++)