( “树” 之 DFS) 337. 打家劫舍 III ——【Leetcode每日一题】

news/2024/7/7 22:40:02

337. 打家劫舍 III

小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为 root

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

给定二叉树的 root 。返回 在不触动警报的情况下 ,小偷能够盗取的最高金额 。

示例 1:

在这里插入图片描述

输入: root = [3,2,3,null,3,null,1]
输出: 7
解释: 小偷一晚能够盗取的最高金额 3 + 3 + 1 = 7

示例 2:

在这里插入图片描述

输入: root = [3,4,5,1,3,null,1]
输出: 9
解释: 小偷一晚能够盗取的最高金额 4 + 5 = 9

提示:

  • 树的节点数在 [ 1 , 1 0 4 ] [1, 10^4] [1,104] 范围内
  • 0 < = N o d e . v a l < = 1 0 4 0 <= Node.val <= 10^4 0<=Node.val<=104

思路:DFS

分析:

每个节点都有不偷两种可能,但是有一定的限制,如下:

  • 若父节点不偷,子节点既能偷,也能不偷
  • 若父节点,子节点只能不偷

解法:
由于每个节点都有两种可能,所以我们需要一个一维数组来保留这两种可能:

  • 若当前节点不偷,其左孩子和有孩子既能偷,也能不偷, 取最大值,状态转移方程为:
    r e s [ 0 ] = m a x ( l e f t [ 0 ] , l e f t [ 1 ] ) + M a t h . m a x ( r i g h t [ 0 ] , r i g h t [ 1 ] ) res[0] = max(left[0], left[1]) + Math.max(right[0], right[1]) res[0]=max(left[0],left[1])+Math.max(right[0],right[1])
  • 若父节点,当前节点的金额加上子节点只能不偷时的金额,状态转移方程为:
    r e s [ 1 ] = r o o t . v a l + l e f t [ 0 ] + r i g h t [ 0 ] res[1] = root.val + left[0] + right[0] res[1]=root.val+left[0]+right[0]
  • 递归即可求出小偷能够盗取的最高金额。

代码:(Java、C++)

Java

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int rob(TreeNode root) {
        //刚开始时,该节点既能偷,也能不偷, 取最大值
        int[] res = takeOrNot(root);
        return Math.max(res[0], res[1]);
    }
    public int[] takeOrNot (TreeNode root){
        if(root == null) return new int[2];
        int[] res = new int[2];
        int[] left = takeOrNot(root.left);
        int[] right = takeOrNot(root.right);
        //如果没有偷当前节点,则其左孩子和有孩子既能偷,也能不偷, 取最大值
        res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
        
        //如果偷了当前节点,则其左孩子和有孩子都不能偷
        res[1] = root.val + left[0] + right[0];

        return res;
    }
}

C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int rob(TreeNode* root) {
        vector<int> res = takeOrNot(root);
        return max(res[0], res[1]);
    }
    vector<int> takeOrNot (TreeNode* root){
        if(root == NULL) return {0, 0};
        vector<int> res = {0, 0};
        vector<int> left = takeOrNot(root->left);
        vector<int> right = takeOrNot(root->right);
        //如果没有偷当前节点,则其左孩子和有孩子既能偷,也能不偷, 取最大值
        res[0] = max(left[0], left[1]) +max(right[0], right[1]);
        
        //如果偷了当前节点,则其左孩子和有孩子都不能偷
        res[1] = root->val + left[0] + right[0];

        return res;
    }
};

运行结果:

在这里插入图片描述

复杂度分析:

  • 时间复杂度 O ( n ) O(n) O(n),其中 n 为树的结点数目。
  • 空间复杂度 O ( n ) O(n) O(n)。递归栈最坏情况下需要 O ( n ) O(n) O(n)的空间。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我 leetCode专栏,每日更新!

注: 如有不足,欢迎指正!


http://lihuaxi.xjx100.cn/news/1049372.html

相关文章

Java版本的工程项目管理系统源代码之工程项目管理系统面临的挑战

​ ​工程项目管理系统是指从事工程项目管理的企业&#xff08;以下简称工程项目管理企业&#xff09;受业主委托&#xff0c;按照合同约定&#xff0c;代表业主对工程项目的组织实施进行全过程或若干阶段的管理和服务。 ​系统定义 工程项目管理企业不直接与该工程项目的总承包…

vba:文件夹和文件夹的处理,dir

Option Explicit 1 判断文件夹是否存在 dir函数的第二个参数是vbdirectory时可以返回路径下的指定文件和文件夹&#xff0c;如果结果为""&#xff0c;则表示不存在。 Sub w1() If Dir(ThisWorkbook.path & "\2011年报表2", vbDirectory) &q…

测绘与设计之间的鸿沟:坐标系,教你如何将CAD与测绘数据准确叠加

一、背景 2008年&#xff0c;我国推出了2000国家大地坐标系&#xff08;以下简称国家2000坐标系&#xff09;&#xff0c;截至2022年&#xff0c;国家2000坐标系在自然资源领域已经取得了较高的普及率&#xff0c;但在工程建设领域的普及率依旧比较低&#xff0c;很多工程项目…

如何将matlab的m文件转换成python文件

因为matlab的内存实在太大了&#xff0c;所以我只在实验室电脑安装了matlab&#xff0c;自己电脑没有安装&#xff0c;现在跑实验需要把matlab文件转成python文件。在网上找到可以使用smop小工具。 我是在本地的anaconda转换的。先创建一个新环境到指定路径 conda create --pr…

如何做好技术管理

1、帮助员工做好个人中长期发展目标规划 主管应该跟员工一起确认员工任期内的中长期成长和发展目标&#xff0c;让员工能够在任期内发挥最大的作用和价值&#xff0c;同时能够尽可能地让员工在任期内达成自己期望的成长目标。对管理者来说有一件很重要的事情&#xff0c;就是能…

大数据实战 --- 世界新冠疫情数据分析

目录 开发环境 数据描述 功能需求 数据准备 统计计算 Hbase Hive 分析数据 开发环境 HadoopHiveSparkHBase 启动Hadoop&#xff1a;start-all.sh 启动zookeeper&#xff1a;zkServer.sh start 启动Hive&#xff1a; nohup hiveserver2 1>/dev/null 2>&1 &…

深度学习第J6周:ResNeXt-50实战解析

目录 一、模型结构介绍 二、前期准备 三、模型 三、训练运行 3.1训练 3.2指定图片进行预测 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊] &#x1f4cc; …

WebServer项目(四)->(基于Proactor的c++)Web服务器简介及简单实现

基于Proactor的cWeb服务器项目 WebServer项目(四)-&#xff1e;(基于Proactor的c)Web服务器简介及简单实现1.Web Server&#xff08;网页服务器&#xff09;2.HTTP协议(应用层的协议)3.HTTP 请求报文格式4.HTTP响应报文格式5.HTTP请求方法6.HTTP状态码7.服务器编程基本框架8.两…