首页 > 其他分享 >2024.2.7力扣每日一题——二叉树的堂兄弟节点2

2024.2.7力扣每日一题——二叉树的堂兄弟节点2

时间:2024-03-31 17:01:14浏览次数:25  
标签:queue 2024.2 right int sum 力扣 二叉树 节点 left

2024.2.7

题目来源

力扣每日一题;题序:2461

我的题解

方法一 哈希表+层序遍历(自己的想法,硬在每一层去算)

使用两个哈希表分别映射parent <子节点,父节点>,children<父节点,子节点列表>。children需要首先将将根节点加入,然后使用层序遍历的方式遍历遍历每一层,并在遍历过程中记录该层所有节点的和sum,以及parent和children,然后使用一个列表存储一层的所有节点(因为层序遍历过后就不知道那些节点是该层的了),然后根据parent找到节点的父节点,再根据children找到自己父节点下的所有子节点,再计算自己父节点下的所有节点的和sub,然后将自己的值改变为sum-sub(这里需要使用数组暂存,否则计算该层后面的节点时会出现问题)。

时间复杂度:应该是O( n 2 n^2 n2)。
空间复杂度:O(n)

public TreeNode replaceValueInTree(TreeNode root) {
    Map<TreeNode,List<TreeNode>> children=new HashMap<>();
    Map<TreeNode,TreeNode> parent=new HashMap<>();
    Queue<TreeNode> queue=new LinkedList<>();
    queue.offer(root);
    List<TreeNode> l=new LinkedList<>();
    l.add(root);
    children.put(null,l);
    while(!queue.isEmpty()){
        int sz=queue.size();
        List<TreeNode> list=new LinkedList<>(queue);
        //计算当前层所有节点的和
        int sum=0;
        for(int i=0;i<sz;i++){
            TreeNode t=queue.poll();
            sum+=t.val;
            l=new LinkedList<>();
            if(t.left!=null){
                queue.offer(t.left);
                parent.put(t.left,t);
                l.add(t.left);
            }
            if(t.right!=null){
                queue.offer(t.right);
                parent.put(t.right,t);
                l.add(t.right);
            }
            children.put(t,l);
        }
        //暂存需要改变的值
        int[] v=new int[sz];
        int i=0;
        for(TreeNode t:list){
        	//查找当前节点的父节点下的所有节点
            l=children.get(parent.get(t));
            int sub=0;
            for(TreeNode tt:l){
                sub+=tt.val;
            }
            v[i++]=sum-sub;
        }
        i=0;
        for(TreeNode t:list){
            t.val=v[i++];
        }
    }
    return root;
}
方法二 广度优先遍历(官方题解,在上一层求下一层)

在广度优先搜索的过程中,通过第 n−1层去遍历第 n层的节点时,可以顺便统计第 n 层节点的和 sum。由于更新 x 的值时需要知道 y 的值(有可能不存在),因此需要通过 n−1 层对第 n 层进行第二次遍历,这时就可以使用 sum−x−y 更新 x 的值了。

时间复杂度:O(n)。
空间复杂度:O(n)

 public TreeNode replaceValueInTree(TreeNode root) {
    // 根节点必然为0
    root.val=0;
    Queue<TreeNode> queue=new LinkedList<>();
    queue.offer(root);
    while(!queue.isEmpty()){
        int sz=queue.size();
        int sum=0;
        //计算下一层的所有节点之和
        for(TreeNode t:queue){
            if(t.left!=null)
                sum+=t.left.val;
            if(t.right!=null)
                sum+=t.right.val;
        }
        for(int i=0;i<sz;i++){
            TreeNode t=queue.poll();
            //非堂兄弟的兄弟节点的和
            int sub=(t.left!=null?t.left.val:0)+(t.right!=null?t.right.val:0);
            // 左子节点
            if(t.left!=null){
                t.left.val=sum-sub;
                queue.offer(t.left);
            }
            // 右子节点
            if(t.right!=null){
                t.right.val=sum-sub;
                queue.offer(t.right);
            }
        }
    }
    return root;
}

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈

标签:queue,2024.2,right,int,sum,力扣,二叉树,节点,left
From: https://blog.csdn.net/weixin_42075274/article/details/137201122

相关文章

  • 2024.2.8力扣每日一题——二叉树的堂兄弟节点
    2024.2.8题目来源我的题解方法一层序遍历方法二深度优先遍历题目来源力扣每日一题;题序:993我的题解方法一层序遍历使用层序遍历,先判断x或y是否是根节点,若是则x和y必然不可能是堂兄弟节点。每次遍历当前层时判断下一层是否出现x和y,若x和y分别出现在该节点的......
  • 【每周例题】力扣 C++ 二叉树的最小深度
    二叉树的最小深度题目二叉树的最小深度题目分析1.首先我们可以处理最小深度为0与最小深度为1的情况:最小深度为0:头结点为空;root==nullptr最小深度为1:root->left==nullptr&&root->right==nullptr2.接下来分为左右子树处理,我们可以用递归来计算最小深度3.最后比较左......
  • 【每周例题】力扣 C++ 搜索插入位置
    搜索插入位置题目搜索插入位置 题目分析1.第一个想法肯定是暴力遍历,找到了就输出下标,找不到就对比前后两个数字,寻找合适的位置插入。2.需要注意一点,我们需要再一开始就对比target与数组最后一个数的大小,如果比数组最后一个数大,直接返回数组长度3.第二个想法就是缩短寻找的......
  • LeetCodeHot100 二叉树 94. 二叉树的中序遍历 104. 二叉树的最大深度 101. 对称二
    94.二叉树的中序遍历https://leetcode.cn/problems/binary-tree-inorder-traversal/description/?envType=study-plan-v2&envId=top-100-liked//递归//List<Integer>resList;//publicList<Integer>inorderTraversal(TreeNoderoot){//re......
  • 力扣HOT100热题宝典--第4节
    ......
  • L2-011 玩转二叉树
    和L2-006是一样的。正常建树,只是在BFS的时候先放右儿子。L2-006树的遍历https://www.cnblogs.com/chengyiyuki/p/18106375代码:#include<bits/stdc++.h>usingnamespacestd;constintN=40;intpre[N],in[N];intL[N],R[N];intbuild(intal,intar,intbl,int......
  • 力扣回溯算法--总结篇
    前言期末考试加上寒假两个月,一直没有动力,差不多三个月没写题了。最近写题也没有及时写文章总结,实在不知道如何开始,但是也得开始啊。干脆写个总结吧,再开始每天坚持写题写文章。玩了两个月,很多事情没有完成,很多东西也忘得差不多了,得抓紧时间捡起来,坚持输入,坚持输出。内容这些......
  • 算法学习——LeetCode力扣动态规划篇1
    算法学习——LeetCode力扣动态规划篇1509.斐波那契数509.斐波那契数-力扣(LeetCode)描述斐波那契数(通常用F(n)表示)形成的序列称为斐波那契数列。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也就是:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2......
  • Offer必备算法18_栈_五道力扣题详解(由易到难)
    目录①力扣1047.删除字符串中的所有相邻重复项解析代码②力扣844.比较含退格的字符串解析代码③力扣227.基本计算器II解析代码④力扣394.字符串解码解析代码⑤力扣946.验证栈序列解析代码本篇完。①力扣1047.删除字符串中的所有相邻重复项1047.删除字符......
  • 【力扣hot100】160.相交链表
    相交链表给你两个单链表的头节点headA和headB,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回null。图示两个链表在节点c1开始相交:题目数据保证整个链式结构中不存在环。注意,函数返回结果后,链表必须保持其原始结构。示例1:输......