【刷题】在二叉树中分配硬币

给定一个二叉树,每个节点含有一定数量的硬币,目标是通过移动硬币使得每个节点恰好拥有一枚硬币。每次移动可以从一个节点移动一枚硬币到相邻节点。文章介绍了使用深度优先搜索(DFS)的递归方法来解决此问题,计算每个节点需要移动的硬币数,并返回总的移动次数。
摘要由CSDN通过智能技术生成

在二叉树中分配硬币

https://leetcode.cn/problems/distribute-coins-in-binary-tree/description/

描述

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

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

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

示例

在这里插入图片描述

思路

在这里插入图片描述

一般二叉树解法以递归居多,精髓就是大事化小小事化了。这道题可以先从三个节点看起,如同上面框框所示,节点123要想达成平衡,需要移动几次?节点2有2个金币,节点3有4个,所以达成平衡需要节点2向节点1移动1个金币,也就是2-1,节点3需要向节点1移动3个金币,也就是4-1。所以现在总共移动了**(2-1)+(4-1)=4次**。
次数有了,为什么减1也知道,因为它要留一个,那怎么求这个2和4呢?
很简单,2或4=左子节点给它的+右子节点给它的+本身有的,左子节点给它的=另一个(2-1)或(4-1),所以我们设递归的关键函数dfs=func(node *TreeNode) int 返回值就是这个(2-1)或(4-1)

dfs = func(node *TreeNode) int {
		var l, r int
		if node == nil {
			return 0
		}
		if node.Left != nil {
			l = dfs(node.Left)
		}
		if node.Right != nil {
			r = dfs(node.Right)
		}
		ans += abs(l) + abs(r) // 左右子节点可能是亏的 但是移动次数一定是正的
		return l + r + node.Val - 1
	}

最终代码如下

func distributeCoins(root *TreeNode) int {
	var ans int
	var dfs func(node *TreeNode) int
	dfs = func(node *TreeNode) int {
		var l, r int
		if node == nil {
			return 0
		}
		if node.Left != nil {
			l = dfs(node.Left)
		}
		if node.Right != nil {
			r = dfs(node.Right)
		}
		ans += abs(l) + abs(r)
		return l + r + node.Val - 1
	}
	dfs(root)
	return ans
}

func abs(i int) int {
	if i < 0 {
		return -i
	}
	return i
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值