深度优先搜索LeetCode979. 在二叉树中分配硬币

给你一个有 n 个结点的二叉树的根结点 root ,其中树中每个结点 node 都对应有 node.val 枚硬币。整棵树上一共有 n 枚硬币。

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

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

深度优先搜索LeetCode979. 在二叉树中分配硬币_第1张图片

每个硬币移动一次就会经过一条边, 原问题可用转换为, 所有边被经过的次数之和。

二叉树中每一条边会连接一个子树,这个子树多的硬币会经过这条边,少的硬币会从其他地方运到该子树。

所以每个边被经过的次数,就是该边对应的子树中  节点个数  和  金币个数之差  的绝对值。

可以使用dfs来做。

vectordfs(node *root):表示以root为根节点的树中 节点个数 和 金币个数 ,v[0]表示节点个数,v[1]表示金币个数。

vectordfs(root):

  vectorv,left,right;

       if(root->left) 

             left  = dfs (root->left);res += abs(left[0]-left[1]); 

      if(root->right)

             right  = dfs (root->right); res += abs(right[0]-right[1]);

      v[0]=left[0]+right[0]+1;

      v[1]=left[1]+right[1]+root->val;

     return v;  

       

 

class Solution {
public: 
    int res=0;
    vectordfs(TreeNode *root){
        vectorv(2,0);
        vectorleft(2,0);
        vectorright(2,0); 
        if(root->left){
            left = dfs(root->left);
        }
        if(root->right){
            right = dfs(root->right); 
        }
        res += abs(left[0]-left[1]);
        res += abs(right[0]-right[1]);
        v[0]=left[0]+right[0]+1;
        v[1]=left[1]+right[1]+root->val;
        return v;
    }
    int distributeCoins(TreeNode* root) {
        dfs(root);
        return res;
    }
};

你可能感兴趣的:(深度优先,算法)