当前位置: 首页 > news >正文

LeetCode337:打家劫舍III

要求

小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root 。除了 root 之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连的房子在同一天晚上被打劫 ,房屋将自动报警。

给定二叉树的 root 。返回在不触动警报的情况下, 小偷能够盗取的最高金额 。
在这里插入图片描述


在这里插入图片描述

思路

不能盗取父子相连的房子

方法一:记忆化搜索
把每次的结果存储起来,下次再计算的话,从缓存中取,避免重复计算;二叉树不适合数组存储,所以使用哈希表进行存储结果

public int rob(TreeNode root) {
    HashMap<TreeNode, Integer> map= new HashMap<>();
    return robInternal(root, map);
}

public int robInternal(TreeNode root, HashMap<TreeNode, Integer> map) {
    if (root == null) return 0;
    if (map.containsKey(root)) return map.get(root);
    int money = root.val;

    if (root.left != null) {
        money += (robInternal(root.left.left, map) + robInternal(root.left.right, map));
    }
    if (root.right != null) {
        money += (robInternal(root.right.left, map) + robInternal(root.right.right, map));
    }
    int result = Math.max(money, robInternal(root.left, map) + robInternal(root.right, map));
    map.put(root, result);
    return result;
}


方法二:动态规划
从下往上遍历 —> 从子节点往父节点去遍历,一层层向上汇报,也就是后序遍历:左右根

1、状态定义:dp[node][j] :这里node表示一个以node为根节点的树,规定了是否偷取能获得最大值

  • j = 0,表示node节点不偷取;
  • j = 1,表示node节点偷取;

2、推导状态转移方程:根据当前节点是否偷取,进行转移

  • 如果不偷取当前节点,左右子节点都可以偷或不偷,选最大值
  • 如果偷取当前节点,左右子节点都不可以进行偷取

3、初始化:节点为空,返回0,对应后序遍历时候的递归终止条件
4、在根节点时,返回两者状态最大值

public class LeetCode337 {
    public int rob(TreeNode root) {
        int[] res = dfs(root);
        return Math.max(res[0],res[1]);
    }

    private int[] dfs(TreeNode root) {
        //终止条件,
        if (root == null) {
            return new int[]{0, 0};
        }
        //后序遍历:先计算左右子节点的值,在计算当前结点的值
        int[] left = dfs(root.left);
        int[] right = dfs(root.right);

        //dp[0]:以当前node为根节点的子树能够偷取的最大价值,规定node节点不偷
        //dp[1]:以当前node为根节点的子树能够偷取的最大价值,规定node节点偷
        int[] dp = new int[2];

        dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        dp[1] = root.val + left[0] + right[0];
        return dp;
    }
}

相关文章:

  • 【飞桨PaddleSpeech语音技术课程】— 语音识别-流式服务-模型部分
  • isomap降维算法--学习笔记
  • 【Linux】yum vim 基础工具的使用
  • QT学习_03_坐标系统和内存回收机制
  • cookies,session,token都是相对安全,并不能完全防窃取
  • 在Ubuntu22.04条件下,如何打开树莓派4B的串口
  • 初识Docker
  • PMP每日一练 | 考试不迷路-10.29(包含敏捷+多选)
  • SSL证书验证原理和https加密
  • Python实现秒杀抢购某宝商品,不再害怕双十一抢不到了
  • 瞪羚优化算法(Gazelle Optimization Algorithm,GOA)
  • CSS3入门
  • 【SQL优化】海量数据大页码MySQL查询该如何优化
  • 乐吾乐le5le-Topology为智慧水务可视化赋能(一)
  • 【node进阶】深入浅出---MVC设计模式RESTful风格
  • Docker下部署自己的LNMP工作环境
  • SpiderData 2019年2月13日 DApp数据排行榜
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • WebSocket使用
  • XForms - 更强大的Form
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 构造函数(constructor)与原型链(prototype)关系
  • 目录与文件属性:编写ls
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #NOIP 2014# day.1 T2 联合权值
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (13)Hive调优——动态分区导致的小文件问题
  • (2)Java 简介
  • (8)STL算法之替换
  • (ibm)Java 语言的 XPath API
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (黑马C++)L06 重载与继承
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (一)Dubbo快速入门、介绍、使用
  • (译) 函数式 JS #1:简介
  • (译)2019年前端性能优化清单 — 下篇
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)机器学习的数学基础(1)--Dirichlet分布
  • .Family_物联网
  • .net core 控制台应用程序读取配置文件app.config
  • .Net的C#语言取月份数值对应的MonthName值
  • @Autowired自动装配
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [BZOJ 3531][Sdoi2014]旅行(树链剖分+线段树)
  • [BZOJ] 2427: [HAOI2010]软件安装
  • [C#]使用PaddleInference图片旋转四种角度检测
  • [CareerCup] 2.1 Remove Duplicates from Unsorted List 移除无序链表中的重复项
  • [Codeforces] number theory (R1600) Part.11
  • [Codeforces1137D]Cooperative Game
  • [GN] Vue3.2 快速上手 ---- 核心语法2