zl程序教程

您现在的位置是:首页 >  其他

当前栏目

【算法训练营day48】LeetCode198. 打家劫舍 LeetCode213. 打家劫舍II LeetCode337. 打家劫舍III

2023-04-18 15:20:48 时间

LeetCode198. 打家劫舍

题目链接:198. 打家劫舍

独上高楼,望尽天涯路

dp[i]表示的是偷窃0-i房屋所能获得的最大金额。

class Solution {
public:
    int rob(vector<int>& nums) {
        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];
    }
};

慕然回首,灯火阑珊处

代码一样,题解的思路更清晰。

决定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],即考 虑i-1房,(注意这里是考虑,并不是一定要偷i-1房,这是很多同学容易混淆的点


LeetCode213. 打家劫舍II

题目链接:213. 打家劫舍II

独上高楼,望尽天涯路

感觉算法主体部分还是打家劫舍I的思路。

慕然回首,灯火阑珊处

讨论三种情况,情况一:不包含首尾元素,情况二:不包含首元素,情况三:不包含尾元素。

分析一下可以知道,情况二和情况三包含情况一,这是因为,例如情况三,虽然包含首元素,但是最高金额不一定选首元素,所以只需要考虑情况二和情况三中最大者即可。

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.size() == 1) return nums[0];
        if (nums.size() == 2) return max(nums[0], nums[1]);
        int result1 = robRange(nums, 0, nums.size() - 2); // 情况三
        int result2 = robRange(nums, 1, nums.size() - 1); // 情况二
        return max(result1, result2);
    }
    // 和打家劫舍的思路一样
    int robRange(vector<int>& nums, int start, int end) {
        vector<int> dp(nums.size());
        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 - 2] + nums[i], dp[i - 1]);
        }
        return dp[end];
    }
};

LeetCode337. 打家劫舍III

题目链接:337. 打家劫舍III

独上高楼,望尽天涯路

树有点生疏了,挖个坑,等二刷把树复习了再来看这道题。

慕然回首,灯火阑珊处