9.12 力扣979. 在二叉树中分配硬币

979. 在二叉树中分配硬币 - 力扣(LeetCode)

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

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

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

示例 1:

 

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

示例 2:

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

思路:题目中要求节点数为n,且金币总数也为n,最后要让所有节点的金币数都为1。按多往少给的想法,很难确定金币多的那个节点需要走多少次给到需要金币的节点。

因为获取金币的方式只要父子节点之间进行传递,若从反向思考问题(假设一开始是所有节点都有1个金币,要让节点持有金币情况变成题目给出的情况)

则可以知道一个节点需要给左孩子x个(可以是负数,负数理解孩子节点给父节点金币)金币,给右孩子y个金币,传递次数=abs(x)+abs(y),且此时该节点需要从父节点获得的金币个数为node->val+x+y-1(node本来就有1个金币,要给孩子x+y个金币,自己要有node->val个金币,多出来则)

从底往上推,叠加每个节点作为父节点时传递金币的次数。

/**
 * 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 dfs(TreeNode* root,int& ret)
    {
        if(root==nullptr) return 0;
        int left=0,right=0;
        //判断需要给左、右孩子多少个金币
        if(root->left) left=dfs(root->left,ret); 
        if(root->right) right=dfs(root->right,ret);
        //结果为所有左、右绝对值依次相加
        ret+=abs(left)+abs(right);
        //返回此子树需要“接收”金币的次数
        return root->val+left+right-1;
    }
    int distributeCoins(TreeNode* root) {
        int ret=0;
        dfs(root,ret);
        return ret;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值