代码随想录第四十一天(一刷&&C语言)|打家劫舍&&打家劫舍II&&打家劫舍III

发布时间:2023年12月25日

创作目的:为了方便自己后续复习重点,以及养成写博客的习惯。

一、打家劫舍

思路:参考carl文档

1、确定dp数组以及下标的含义:下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]。

2、确定递推公式:dp[i]取决于第i房间偷还是不偷。偷第i房间,dp[i] = dp[i - 2] + nums[i] ,即:第i-1房不考虑,找出 下标i-2(包括i-2)以内的房屋,最多可以偷窃的金额为dp[i-2] 加上第i房间偷到的钱。如果不偷第i房间,那么dp[i] = dp[i - 1]。取dp[i]最大值,即dp[i] = max(dp[i - 2] + nums[i], dp[i - 1]);

3、dp数组如何初始化:递推公式的基础就是dp[0] 和 dp[1]。dp[0] 一定是 nums[0],dp[1]是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1])。

代码如下:

4、确定遍历顺序:dp[i - 2] 和 dp[i - 1] 推导出dp[i] ,遍历是从前到后的。

5、举例推导dp数组

ledcode题目:https://leetcode.cn/problems/house-robber/description/

AC代码:

int rob(int* nums, int numsSize){                             
    int dp0 = 0;                // dp0: 不偷这个屋子能窃到的最高金额
    int dp1 = nums[0]; // dp1: 偷这间屋子能窃到的最高金额
    for (int i = 1; i < numsSize; i++) {
        int dp0new = fmax(dp0, dp1);
        int dp1new = dp0 + nums[i];
        dp0 = dp0new;
        dp1 = dp1new;
    }
    return fmax(dp0, dp1);
}

二、打家劫舍II

思路:参考carl文档

相比于上一题考虑成环的情况:

1、考虑不包含首尾元素

2、考虑包含首元素,不包含尾元素

3、考虑包含尾元素,不包含首元素

lecode题目:https://leetcode.cn/problems/house-robber-ii/

AC代码:

int robRange(int* nums, int start, int end) {
    int first = nums[start], second = fmax(nums[start], nums[start + 1]);
    for (int i = start + 2; i <= end; i++) {
        int temp = second;
        second = fmax(first + nums[i], second);
        first = temp;
    }
    return second;
}

int rob(int* nums, int numsSize) {
    if (numsSize == 1) {
        return nums[0];
    } else if (numsSize == 2) {
        return fmax(nums[0], nums[1]);
    }
    return fmax(robRange(nums, 0, numsSize - 2), robRange(nums, 1, numsSize - 1));
}

三、打家劫舍III

思路:参考carl文档

采用dfs暴力搜索,其余方法暂时未实验

ledcode题目:https://leetcode.cn/problems/house-robber-iii/

AC代码:

struct SubtreeStatus {
    int selected;
    int notSelected;
};

struct SubtreeStatus dfs(struct TreeNode *node) {
    if (!node) {
        return (struct SubtreeStatus){0, 0};
    }
    struct SubtreeStatus l = dfs(node->left);
    struct SubtreeStatus r = dfs(node->right);
    int selected = node->val + l.notSelected + r.notSelected;
    int notSelected = fmax(l.selected, l.notSelected) + fmax(r.selected, r.notSelected);
    return (struct SubtreeStatus){selected, notSelected};
}

int rob(struct TreeNode *root) {
    struct SubtreeStatus rootStatus = dfs(root);
    return fmax(rootStatus.selected, rootStatus.notSelected);
}

文章来源:https://blog.csdn.net/qq_57729144/article/details/135206421
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。