算法训练营第五十天 | LeetCode 198 打家劫舍、LeetCode 213 打家劫舍II、LeetCode 337 打家劫舍III

LeetCode 198 打家劫舍


代码如下:

cpp 复制代码
class Solution {
public:
    int rob(vector<int>& nums) {
        vector<int> dp(nums.size() + 1, 0);
        dp[1] = nums[0];
        for (int i = 2; i <= nums.size(); i++) {
            dp[i] = max(dp[i - 1] ,dp[i - 2] + nums[i - 1]);
        }
        return dp[nums.size()];
    }
};

LeetCode 213 打家劫舍II


分情况进行讨论即可

cpp 复制代码
class Solution {
public:
    int rob(vector<int>& 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<int>& nums, int start, int end) {
        if (end == start) return nums[start];
        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];
    }
};

LeetCode 137 打家劫舍III


直接用简单版递归会超时

java 复制代码
class Solution {
    public int innerRob(int state, TreeNode root) {
        if (root == null) return 0;
        if (state == 1) {
            return (innerRob(0, root.left) + innerRob(0, root.right));
        } else {
            return Math.max(root.val + innerRob(1, root.left) + innerRob(1, root.right), 
                innerRob(0, root.left) + innerRob(0, root.right));
        }
    }
    public int rob(TreeNode root) {
        if (root == null) return 0;
        return Math.max(root.val + innerRob(1, root.left) + innerRob(1, root.right), 
            innerRob(0, root.left) + innerRob(0, root.right));
    }
}

用哈希表记录下重复子问题就没问题了

java 复制代码
class Solution {
    Map<TreeNode, Integer> choose = new HashMap<TreeNode, Integer>();
    Map<TreeNode, Integer> not_choose = new HashMap<TreeNode, Integer>();
    public void dfs (TreeNode root) {
        if (root == null) return;
        dfs(root.left);
        dfs(root.right);
        choose.put(root, root.val + not_choose.getOrDefault(root.left,0) + not_choose.getOrDefault(root.right,0));
        not_choose.put(root,Math.max(Math.max(choose.getOrDefault(root.left,0) + choose.getOrDefault(root.right,0), not_choose.getOrDefault(root.left,0) + not_choose.getOrDefault(root.right,0)),
            Math.max(choose.getOrDefault(root.left,0) + not_choose.getOrDefault(root.right,0), not_choose.getOrDefault(root.left,0) + choose.getOrDefault(root.right,0))));
    }
    public int rob(TreeNode root) {
        dfs(root);
        return Math.max(choose.getOrDefault(root,0), not_choose.getOrDefault(root,0));
    }
}

优化后代码如下:

java 复制代码
class Solution {
    Map<TreeNode, Integer> choose = new HashMap<TreeNode, Integer>();
    Map<TreeNode, Integer> not_choose = new HashMap<TreeNode, Integer>();
    public void dfs (TreeNode root) {
        if (root == null) return;
        dfs(root.left);
        dfs(root.right);
        choose.put(root, root.val + not_choose.getOrDefault(root.left,0) + not_choose.getOrDefault(root.right,0));
        not_choose.put(root,Math.max(choose.getOrDefault(root.left,0), not_choose.getOrDefault(root.left,0)) + Math.max(choose.getOrDefault(root.right,0), not_choose.getOrDefault(root.right,0)));
    }
    public int rob(TreeNode root) {
        dfs(root);
        return Math.max(choose.getOrDefault(root,0), not_choose.getOrDefault(root,0));
    }
}
相关推荐
ShineWinsu5 小时前
对于C++:继承的解析—上
开发语言·数据结构·c++·算法·面试·笔试·继承
pp起床5 小时前
动态规划 | part05
算法·动态规划
GuangHeAI_ATing5 小时前
国密算法SSD怎么选?这3款国产固态硬盘安全又高速
算法
码农阿豪5 小时前
Nacos 日志与 Raft 数据清理指南:如何安全释放磁盘空间
java·安全·nacos
直有两条腿6 小时前
【大模型】Langchain4j
java·langchain
love530love6 小时前
Scoop 完整迁移指南:从 C 盘到 D 盘的无缝切换
java·服务器·前端·人工智能·windows·scoop
雨泪丶6 小时前
代码随想录算法训练营-Day34
算法
消失的旧时光-19436 小时前
C++ 多线程与并发系统取向(二)—— 资源保护:std::mutex 与 RAII(类比 Java synchronized)
java·开发语言·c++·并发
莫寒清6 小时前
ThreadLocal
java·面试
Yzzz-F6 小时前
牛客寒假算法训练营2
算法