leetcode每日一题-563:二叉树的坡度

leetcode每日一题-563:二叉树的坡度

链接

二叉树的坡度

题目

在这里插入图片描述

分析

简单的dfs问题。首先明确思路,我们需要遍历每一个点,然后求出该点左右子树的值的总和,然后做差,答案累计这个差值即可。那么问题就转化到求每个节点左右子树值的综合上面,同样是一个dfs问题,但是这个问题有一个优化,我们在之后的代码部分进行详细的分析。

代码

C++

/**
 * 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 res = 0;
    int findTilt(TreeNode* root) {
        // 首先对节点判空,如果是空,那么结果为0,直接返回即可.
        if(root == nullptr) return res;
        // 遍历整个树
        dfs(root);
        // 返回结果值
        return res;
    }

    void dfs(TreeNode* root)
    {
        // 分别记录左右子树值的总和,初始值为0
        int l = 0, r = 0;
        // 如果存在左子树就更新左子树值的总和
        if(root->left) l = sum(root->left);
        // 如果存在右子树就更新右子树值的总和
        if(root->right) r = sum(root->right);
        // 答案记录一下差值
        res += abs(l - r);
        // 如果存在左节点就计算左节点的坡度
        if(root->left) dfs(root->left);
        // 如果存在右节点就计算右节点的坡度
        if(root->right) dfs(root->right);
    }

    int sum(TreeNode* root) 
    {
        // 计算当前节点值的总和
        // 左子树的值
        int l = 0;
        // 右子树的值
        int r = 0;
        // 如果存在左子树就更新左子树的值(递归更新)
        if(root->left) l = sum(root->left);
        // 如果存在右子树就更新右子树的值(递归更新)
        if(root->right) r = sum(root->right);
        // 返回当前节点值的总和
        return root->val + l + r;
    }
};

C++

优化

我们经过简单的思考就可以发现,解法一实在是太繁琐了,我们每遍历一个点,就需要查询以当前结点为跟的整个树,其中存在大量的重复,那么是否可以优化这个过程呢?我们仔细观察,其实在计算差值的时候,我们也是遍历了整个树,那么我们可以可以边更新边遍历,我们先计算底层的值,然后用底层的值来更新更高一层的值,显然是可以的。

/**
 * 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 {

    int res = 0;

public:
    int findTilt(TreeNode* root) {
       	// 如果根节点非空就递归遍历树
        if(root) dfs(root);
        // 返回结果
        return res;
    }

    // 边计算差值边求当前节点的总和,从底层开始向上遍历
    int dfs(TreeNode* root)
    {
        // 如果是叶子,就返回当前值
        if(!root->left and !root->right) return root->val;

        // 计算当前当前节点的左右子树总和,默认值为0
        int l = 0, r = 0;
        // 如果存在左子树就更新l,此时,先去计算底层的值,向下递归
        if(root->left) l = dfs(root->left);
        // 如果存在右子树就更新r,此时,先去计算底层的值,向下递归
        if(root->right) r = dfs(root->right);
        // 记录下差值
        res += abs(l - r);
        // 返回当前节点的值的总和
        return l + r + root->val;
    }
};

Java

class Solution {
    int ans = 0;

    public int findTilt(TreeNode root) {
        dfs(root);
        return ans;
    }

    public int dfs(TreeNode node) {
        if (node == null) {
            return 0;
        }
        int sumLeft = dfs(node.left);
        int sumRight = dfs(node.right);
        ans += Math.abs(sumLeft - sumRight);
        return sumLeft + sumRight + node.val;
    }
}

作者:LeetCode-Solution

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
)">
下一篇>>