LeetCode-树-好叶子节点对数

给定一棵二叉树和一个距离distance,如果两个叶节点间的最短路径长度小于等于distance,则它们是一对好叶子节点。此题要求计算树中好叶子节点对的数量。通过二叉树的后续遍历,记录叶子节点高度,用两层循环检查左右子树的叶子节点是否满足条件,最后递归求解。
摘要由CSDN通过智能技术生成

题干:

给你二叉树的根节点 root 和一个整数 distance 。

如果二叉树中两个 叶 节点之间的 最短路径长度 小于或者等于 distance ,那它们就可以构成一组 好叶子节点对 。

返回树中 好叶子节点对的数量 。

示例 1:

输入:root = [1,2,3,null,4], distance = 3
输出:1
解释:树的叶节点是 3 和 4 ,它们之间的最短路径的长度是 3 。这是唯一的好叶子节点对。
示例 2:

输入:root = [1,2,3,4,5,6,7], distance = 3
输出:2
解释:好叶子节点对为 [4,5] 和 [6,7] ,最短路径长度都是 2 。但是叶子节点对 [4,6] 不满足要求,因为它们之间的最短路径长度为 4 。
示例 3:

输入:root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3
输出:1
解释:唯一的好叶子节点对是 [2,5] 。
示例 4:

输入:root = [100], distance = 1
输出:0
示例 5:

输入:root = [1,1,1], distance = 2
输出:1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-good-leaf-nodes-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

 

解析:

二叉树的后续遍历

1. 计算出左子树中所有的叶子节点并记录每个叶子节点的高度

2. 计算出右子树中所有的叶子节点并记录每个叶子节点的高度

3. 当前节点,对返回的每个叶子节点的高度加1,并将合格的叶子节点记录下来

4. 对当前节点的左右子树返回叶子节点高度进行相加,如果在distance内,则满足条件,结果数+1

    使用两层for循环,左子树的每个叶子节点与右子树的每个叶子节点进行配对比较。

依次递归到根节点,求出结果

代码如下:

/**
 * 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 countPairs(TreeNode* root, int distance) {
        int ans=0;
        BackTravel(root,distance,ans);
        return ans;
    }

    //返回的是叶子节点个数,并且记录每个节点的高度
    vector<int> BackTravel(TreeNode* node, int distance, int& ans)
    {
        //当前节点如果是叶子节点,则返回一个高度为0
        //此处也是递归终止条件
        if(node->left == nullptr && node->right==nullptr)
        {
            vector<int> ret;
            ret.push_back(0);
            return ret;
        }

        vector<int> res;        //当前节点的满足条件的叶子节点数,值代表高度
        vector<int> left;       //当前节点左子树满足条件的叶子节点数
        vector<int> right;      //当前节点右子树满足条件的叶子节点数
        //获得左子树叶子节点
        if(node->left)
             left= BackTravel(node->left,distance,ans);
        //判断满足条件的叶子节点,存放到res
        for(size_t i=0; i<left.size(); i++)
        {
            if(++left[i]<distance)
                res.push_back(left[i]);
        }
        //获得右子树叶子节点
        if(node->right)
            right = BackTravel(node->right,distance,ans);
        //判断满足条件的叶子节点,存放到res
        for(size_t i=0; i<right.size(); i++)
        {
            if(++right[i] <= distance)
            {
                res.push_back(right[i]);
            }
        }

        //左右子树的叶子节点进行全配对组合,看是否满足条件,如果满足条件,则结果+1
        for(size_t i=0; i<left.size(); i++)
        {
            for(size_t j=0; j<right.size(); j++)
            {
                if(left[i]+right[j] <= distance)
                {
                    ans++;
                }
            }
        }
        //返回当前节点满足条件的所有叶子节点的高度
        return res;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值