【979. 在二叉树中分配硬币】

news2024/11/23 12:02:29

来源:力扣(LeetCode)

描述:

给定一个有 N 个结点的二叉树的根结点 root,树中的每个结点上都对应有 node.val 枚硬币,并且总共有 N 枚硬币。

在一次移动中,我们可以选择两个相邻的结点,然后将一枚硬币从其中一个结点移动到另一个结点。(移动可以是从父结点到子结点,或者从子结点移动到父结点。)。

返回使每个结点上只有一枚硬币所需的移动次数。

示例 1:

1

输入:[3,0,0]
输出:2
解释:从树的根结点开始,我们将一枚硬币移到它的左子结点上,一枚硬币移到它的右子结点上。

示例 2:

2

输入:[0,3,0]
输出:3
解释:从根结点的左子结点开始,我们将两枚硬币移到根结点上 [移动两次]。然后,我们把一枚硬币从根结点移到右子结点上。

示例 3:

3

输入:[1,0,2]
输出:2

示例 4:

4

输入:[1,0,0,null,3]
输出:4

提示:

  • 1<= N <= 100
  • 0 <= node.val <= N

方法:深度优先搜索

思路与算法

题目中要求求出移动步数,设 dfs(a) 表示若使得以 a 为根节点的子树满足每个节点均只有一个金币时,节点 a 的父节点需要从节点 a 「拿走」的金币数目,我们可以定义如下:

  • 如果 dfs(a) > 0,则表示节点 a 需要向 a 的父节点移动 dfs(a) 个金币;
  • 如果 dfs(a) = 0,则表示节点 a 与 a 的父节点之间不需要移动;
  • 如果 dfs(a) < 0,则表示节点 a 的父节点需要向 a 移动 ∣dfs(a)∣ 个金币;

综上可知道无论哪个方向移动,节点 a 与其父节点之间的金币移动此时一定为 ∣dfs(a)∣;
设 count(a) 表示当以节点 a 为根节点的子树中含有的二叉树节点数目,设 sum(a) 表示以节点 a 为根节点的子树中含有的二叉树节点的值之和,此时可以知道 dfs(a) = sum(a) − count(a),则可以按照以下几种情形分析:

  • 假设 sum(a) > count(a),即此时子树中金币总数量大于节点的总数量,此时需要向 a 的父节点移动 sum(a) − count(a) 个金币;
  • 假设 sum(a) < count(a),即此时子树中金币总数量小于节点的总数量,此时需要从 a 的父节点需要移动 count(a) − sum(a) 个金币;
  • 假设 sum(a) = count(a),即此时子树中金币总数量等于节点的总数量,此时 a 的父节点与 a 之间不需要移动即可,最优策略一定是 a 的左子树与右子树之间的金币互相移动即可,此处不再证明;

假设当前节点为 node,设 val(node) 表示节点 node 初始时的金币数目,它的左孩子为 left,它的右孩子为 right,则此时可以知道如下:

  • 若要使得左子树每个节点的数目均为 1,此时 node 需要从 left「拿走」的为金币数目 dfs(left),此时 left 与 node 之间需要移动 ∣dfs(left)∣ 次金币;
  • 若要使得右子树每个节点的数目均为 1,此时 node 需要从 right「拿走」的金币数目 dfs(right),此时 right 与 node 之间需要移动 ∣dfs(right)∣ 次金币;
  • 此时根节点的金币总数目即为 move(left) + move(right) + val(node),由于 node 本身需要保留一个金币,此时 node 的根节点需要向它「拿走」的金币数目即为 move(left) + move(right) + val(node) − 1;

综上我们采用递归,每次递归遍历节点 node 时,返回其父节点需要从 node 「拿走」的金币数目,并统计当前节点与其子节点之间的移动金币的次数,我们通过递归遍历即可求得所有节点与其父节点之间的移动金币的次数统计之和即为总的金币移动次数。

  • 由于本题中树中金币的数目与树中节点的数目相等,根据上述推论可以知道根节点 root 一定不需要再向其父节点移动金币。

代码:

class Solution {
public:    
    int distributeCoins(TreeNode* root) {
        int move = 0;

        function<int(const TreeNode *)> dfs = [&](const TreeNode *root) -> int {
            int moveleft = 0;
            int moveright = 0;
            if (root == nullptr) {
                return 0;
            }
            if (root->left) {
                moveleft = dfs(root->left);
            }        
            if (root->right) {
                moveright = dfs(root->right);
            }
            move += abs(moveleft) + abs(moveright);
            return moveleft + moveright + root->val - 1;
        };

        dfs(root);
        return move;
    }
};

执行用时:4 ms, 在所有 C++ 提交中击败了82.91%的用户
内存消耗:13.4 MB, 在所有 C++ 提交中击败了98.49%的用户
复杂度分析
时间复杂度:O(n),其中 n 表示二叉树中节点的数目。只需要遍历一遍即可,因此时间复杂度为 O(n)。
空间复杂度:O(n),其中 n 表示二叉树中节点的数目。递归深度与二叉树的深度有关,其中二叉树的深度最小值为 logn,深度最大值为 n,递归深度最多为 n 层,因此空间复杂度为 O(n)。
author:LeetCode-Solution

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/752152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】list简单介绍

list基本功能介绍 前言正式开始构造函数push_backiteratorpush_frontinserterasespliceremoveuniquereversesortmerge 前言 本篇不会讲太多细节&#xff0c;就说一下STL库中一些函数的基本用法&#xff0c;如果想要了解细节上的东西的话&#xff0c;建议看我string的介绍&…

QT ui_xxx.h: no such file or directory”

使用QT新建子窗口后,编译无法通过 mainwindow.obj:-1: error: LNK2019: 无法解析的外部符号 "public: __cdecl labelwindow::labelwindow(class QWidget *)" (??0labelwindowQEAAPEAVQWidgetZ)&#xff0c;该符号在函数 "private: void __cdecl MainWindow::o…

android studio 添加并读取json配置文件

第一步&#xff1a;在android studio中添加json文件&#xff1b; 第二步&#xff1a;读取文件的函数 private String[] getJosnData(){String result[] null;List<String> list new ArrayList<>();try {//获取本地的Json文件AssetManager assetManager mConte…

界面控件DevExtreme v23.1新版亮点 - 全新的DateRangeBox组件

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序。从Angular和Reac&#xff0c…

【Qt】 自定义列表控件

一、效果图 二、思路 先实现单个item控件&#xff0c;之后根据所需个数new出来插入布局中。item过多时支持滑动操作&#xff0c;可以把item放入scrollArea中&#xff0c;如需实现滑动效果可以使用eventFilter&#xff0c;计算坐标配合scrollArea->verticalScrollBar()->…

2023数字化转型研讨会:RockPlus MOM系统引领制造业变革

7月13日在淄博张店举办的2023年企业数字化转型研讨会上&#xff0c;RockPlus MOM制造运营系统闪耀登场&#xff0c;凭借其将精益生产与信息化相结合的理念&#xff0c;成为会议的一大焦点。该系统是由合共软件精心打造的&#xff0c;目标在供应链管理(SRM)、仓储物流(WMS)、计划…

这么多计算机语言该怎么选

这么多计算机语言该怎么选 选择哪种计算机语言取决于你的需求和目标。以下是一些考虑因素&#xff1a; 你想用语言做什么&#xff1a;首先&#xff0c;你需要确定你的语言选择将主要用于什么目的。是为了编写Web应用程序、移动应用程序、桌面应用程序还是其他类型的应用程序&…

密码学学习笔记(十):Digital Signatures - 数字签名2

ElGamal 签名 密钥生成&#xff1a;随机选取&#x1d465;, 设置&#x1d466; 签名&#xff1a;选一个随机的k&#xff0c;gcd (&#x1d458;, &#x1d45d; − 1) 1 认证&#xff1a;给与一个签名&#x1d70e; (&#x1d45f;, &#x1d460;), 检查它是否满足 工作原…

Java设计模式之行为型-命令模式(UML类图+案例分析)

目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 1、基本实现 2、点餐案例 五、总结 一、基础概念 1、将一个请求封装为一个对象&#xff0c;使您可以用不同的请求对客户进行参数化。 2、对请求排队或记录请求日志&#xff0c;以及支持可撤销的操作。 3、…

赛效:如何在线将多图合为GIF动图

1&#xff1a;点击多图合成GIF。 2&#xff1a;点击页面中间的上传按钮&#xff0c;将图片上传到页面上去。 3&#xff1a;动图参数调整好后&#xff0c;点击下方“生成GIF并下载”&#xff0c;就可以将GIF文件保存到电脑本地了。 如果你想了解更多办公软件及其对应的使用教程&…

.net core 2.1 简单部署IIS运行

netcore的项目不像netFramework那么方便部署到iis还是要费点功夫的 比如我想把这个netcore2.1的项目部署到iis并运行&#xff1a; 按照步骤走&#xff1a; 一、确认自己的netcore环境 1、需要安装下面3个环境包(如果电脑已安装请忽略) 检查是否安装cmd命令&#xff1a;cmd&…

这么看,项目经理根本不可能失业

早上好&#xff0c;我是老原。 不知道做项目经理的朋友们有没有这种感觉&#xff0c;明明项目经理是一个高大上的管理岗位&#xff0c;但为何总觉得自己的工作是一个打杂的&#xff1f; 最近就有一个粉丝朋友来和我吐槽&#xff1a;明明是升职&#xff0c;为啥感觉被坑了。 …

Bard!谷歌对 ChatGPT 的最强反击,悄咪咪的支持中文了!

“ ChatGPT、Bard&#xff0c;哪个是更好的AI人工智能大语言模型。” 01 — ChatGPT 这么火&#xff0c;而且这款产品是 OpenAI 以谷歌的大模型架构 transformer 为基础迭代的。谷歌自然不甘落后&#xff0c;早在3月份推出自家的人工智能大语言模型 Bard&#xff0c;只是当时还…

学科知识图谱学习平台项目 :技术栈Java、Neo4j、MySQL等超详细教学

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

Drools用户手册翻译——第三章 构建,部署,应用和运行(五)可执行规则模型

这应该是Drools的新东西&#xff0c;我之前使用的时候都没注意到还有这么一个东西&#xff0c;据说是可以让Drools变得更高更快更强&#xff0c;这里面有比较详细的介绍&#xff0c;感兴趣就去来看看。 甩锅声明&#xff1a;本人英语一般&#xff0c;翻译只是为了做个笔记&…

N天爆肝数据库——MySQL(4)

本篇文章&#xff0c;主要对多表查询&#xff0c;事务以及体系结构进行知识总结和学习。 期待和大家一起学习进步。标量子查询 子查询返回的结果是单个值&#xff08;数字、字符串、日期等&#xff09;&#xff0c;最简单的形式&#xff0c;这种子查询称标量子查询。常用的操作…

面试题更新之-DOCTYPE html相关问题

文章目录 <!DOCTYPE html>是什么&#xff1f;为什么要在html文件开头加上一个<!DOCTYPE html>DOCTYPE的作用&#xff0c;严格与混杂模式的区别&#xff0c;有何意义HTML5为什么只需要写<!DOCTYPE HTML> 是什么&#xff1f; 是HTML文档的文档类型声明&#xf…

SpringSecurity--权限管理架构介绍

目录 介绍 认证 授权 解决⽅案 Shiro 开发者⾃定义 Spring Security 整体架构 认证 AuthenticationManager&#xff08;认证管理器&#xff09; Authentication SecurityContextHolder 授权 AccessDecisionManager AccessDecisionVoter ConfigAttribute 总结 …

Python在安装包时出现ValueError: check_hostname requires server_hostname和Read timed out

一、ValueError: check_hostname requires server_hostname 出现这个问题基本上是因为开了vpn等网络代理软件造成&#xff0c;关掉代理软件即可解决。 二、Read timed out 在安装python包的时候&#xff0c;出现 Read timed out. 尽管添加了镜像源头py.ini&#xff0c;也添加…