【树】B043_LC_在二叉树中分配硬币(后序遍历)

一、Problem

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

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

返回使每个结点上只有一枚硬币所需的移动次数。
在这里插入图片描述

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

在这里插入图片描述

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

提示:

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

二、Solution

方法一:后序遍历

因为我们要得到子节点的信息,所以后序遍历最佳;又因为最终的形状是每个结点都只有 11 颗金币,那假设某一个叶子结点 node 的金币数为 xx,则结点分配一颗金币所需要的步骤数为(x-1),x1x-1 的结果无外乎几种:

  • x1=0x-1 = 0:表示该结点不需要分配金币(已经有 1 颗金币)
  • x1<0x-1 < 0:表示该结点没有金币,需要被分配
  • x1>0x-1 > 0:表示该结点的金币数大于 11,此时也要将多余的 x1x-1 颗硬币移动

回到该叶子结点 node 的父亲 fa,如果叶子结点需要的硬币数为 1,如果父亲 fa 也没有硬币,那么该父亲 fa 向上传递的信息将会是 -2;但如果 fa 的右子节点有 2 个硬币多余,那么 fa 向上传递的信息将会是 0

class Solution {
public:
	int op;
	int dfs(TreeNode* root) {
		if (root == NULL)
			return 0;
		int l = dfs(root->left), r = dfs(root->right), cur = l+r+root->val;
		op += abs(cur-1);
		return cur-1;
	}
    int distributeCoins(TreeNode* root) {
    	dfs(root);
    	return op;
    }
};

复杂度分析

  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章