LeetCode 2641. 二叉树的堂兄弟节点 II

Problem: 2641. 二叉树的堂兄弟节点 II

思路

首先很明显这是一个搜索题目,立即推bfs或bfs。根据题意,我们仅仅需要预处理出每一层的数值和sum[i]即可。这里我们假设当前节点的父节点为parent,每一个节点的值应当转化为sum[i]减去parent的左右孩子的数值和即可。

解题方法

然后就引入了另外一个问题:怎么预处理出每一层的数值和呢?
这里我们采用了两个方法,方法一为dfs,这个方法很简单,不再赘述。方法二为bfs。假设当前节点为node,在bfs中我们需要将当前节点node的儿子节点放入队列。在这种情况下,我们可以在将儿子节点放入队列的同时计算当前节点node孙子节点所在层的数值和。

复杂度

时间复杂度:

时间复杂度 O ( n ) O(n) O(n)

空间复杂度:

空间复杂度 O ( n ) O(n) O(n)

DFS

//dfs
class Solution {
public:
    int sum[100005] = {0};
    TreeNode* replaceValueInTree(TreeNode* root) {
        
        //求各个层次的数值和
        dfs(root, 0);

        //开始bfs
        int h = 1;
        queue<TreeNode*> q;
        q.push(root);

        while(q.size()){
            int total = q.size();
            for(int i = 0;i < total;i++){
                auto t = q.front();
                q.pop();
                if(h < 3) t->val = 0;//对前两层设值为0

                int lval = t->left ? t->left->val : 0;
                int rval = t->right ? t->right->val : 0;
                if(t->left) {
                    q.push(t->left);
                    t->left->val = sum[h] - lval - rval;
                }
                if(t->right) {
                    q.push(t->right);
                    t->right->val = sum[h] - lval - rval;
                }
            }
            h++;
        }
        return root;
    }

    void dfs(TreeNode* node, int h){
        if(node == nullptr) return ;
        sum[h] += node->val;
        dfs(node->left, h+1);
        dfs(node->right, h+1);
    }
};

BFS

//bfs
class Solution {
public:
    int sum[100005] = {0};
    TreeNode* replaceValueInTree(TreeNode* root) {
        //开始bfs
        int h = 0;
        queue<TreeNode*> q;
        q.push(root);

        while(q.size()){
            int total = q.size();
            for(int i = 0;i < total;i++){
                auto t = q.front();
                q.pop();
                //if(h < 2) t->val = 0;

                int lval = t->left ? t->left->val : 0;
                int rval = t->right ? t->right->val : 0;
                if(t->left) {
                    q.push(t->left);
                    if(t->left->left) sum[h+2] += t->left->left->val;
                    if(t->left->right) sum[h+2] += t->left->right->val;
                    t->left->val = sum[h+1] - lval - rval > 0 ? sum[h+1] - lval - rval : 0;
                }
                if(t->right) {
                    q.push(t->right);
                    if(t->right->left) sum[h+2] += t->right->left->val;
                    if(t->right->right) sum[h+2] += t->right->right->val;
                    t->right->val = sum[h+1] - lval - rval > 0 ? sum[h+1] - lval - rval : 0;
                }
            }
            h++;
        }
        root->val = 0;
        return root;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值