【代码随想录】第六章-二叉树1

server/2025/2/4 14:33:01/

【代码随想录】第六章-二叉树1

  • 第六章 二叉树1
    • 1 二叉树的层序遍历
      • 102. 二叉树的层序遍历
      • 107.二叉树的层序遍历II
      • 199.二叉树的右视图
      • 637.二叉树的层平均值
      • 429.N叉树的层序遍历
      • 515.在每个树行中找最大值
      • 116.填充每个节点的下一个右侧节点指针
      • 117.填充每个节点的下一个右侧节点指针II
      • 104.二叉树的最大深度
      • 559.N叉树的最大深度
      • 111.二叉树的最小深度
    • 2 翻转二叉树
    • 3 对称二叉树
      • 101.对称二叉树
      • 100.相同的树
      • 572.另一棵树的子树
    • 4 完全二叉树的节点个数
    • 5 平衡二叉树
      • 110.平衡二叉树
        • Method1:全局变量
        • Method2:快速返回
    • 6 二叉树的所有路径
    • 7 左叶子之和
      • 404.左叶子之和
    • 8 找树左下角的值
      • 513.找树左下角的值
        • Method1:递归法-先序遍历求二叉树高度
        • Method2:迭代层序遍历


第六章 二叉树1

1 二叉树的层序遍历

102. 二叉树的层序遍历

给你一个二叉树,请你返回其按层序遍历得到的节点值。(即逐层地,从左到右访问所有节点)。
输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]

思路:
用Q.size()记录当前层节点的数量,遍历即可

java">class Solution {List<List<Integer>> list=new ArrayList<>();public List<List<Integer>> levelOrder(TreeNode root) {Deque<TreeNode> Q=new ArrayDeque<>();if(root==null) return list;TreeNode p=root;Q.add(p);while(!Q.isEmpty()){int levelSize = Q.size();  List<Integer> level = new ArrayList<>();for (int i = 0; i < levelSize; i++) {p = Q.poll();level.add(p.val);if (p.left != null) {Q.add(p.left);}if (p.right != null) {Q.add(p.right);}}list.add(level);       }return list;}
}

107.二叉树的层序遍历II

给你二叉树的根节点root,返回其节点值自底向上的层序遍历。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)。
输入:root = [3,9,20,null,null,15,7] 输出:[[15,7],[9,20],[3]]

思路:
list.addFirst(level);使用头插即可


199.二叉树的右视图

给定一个二叉树的根节点root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
输入:root = [1,2,3,null,5,null,4] 输出:[1,3,4]

思路:
只用将每层的最后一个元素的val值加入list集合即可


637.二叉树的层平均值

给定一个非空二叉树的根节点root,以数组的形式返回每一层节点的平均值。与实际答案相差10-5以内的答案可以被接受。
输入:root = [3,9,20,null,null,15,7] 输出:[3.00000,14.50000,11.00000]

思路:
与之前思路一致


429.N叉树的层序遍历

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
输入:root = [1,null,3,2,4,null,5,6] 输出:[[1],[3,2,4],[5,6]]

思路:
层序遍历,无非以前是两个,现在是一串


515.在每个树行中找最大值

给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。
输入:root = [1,3,2,5,3,null,9] 输出:[1,3,9]

思路:
与之前思路一致


116.填充每个节点的下一个右侧节点指针

给定一个完美二叉树,其所有叶子节点都在同一层,每个父节点都有两个子节点。填充它的每个next指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将next指针设置为NULL。初始状态下,所有next指针都被设置为NULL。
输入:root = [1,2,3,4,5,6,7] 输出:[1,#,2,3,#,4,5,6,7,#]

思路:
存好之前的指针,分别进行处理即可


117.填充每个节点的下一个右侧节点指针II

给定一个二叉树,现在并不是完全二叉树
思路:
同116


104.二叉树的最大深度

给定一个二叉树root,返回其最大深度。二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。
输入:root = [3,9,20,null,null,15,7] 输出:3

思路:
如果节点为空,深度为 0;如果左子树为空,递归计算右子树的深度;如果右子树为空,递归计算左子树的深度;如果左右子树都不为空,递归计算左右子树的深度

java">class Solution {public int maxDepth(TreeNode root) {if (root == null) {return 0;}if (root.left == null) {return maxDepth(root.right) + 1;}if (root.right == null) {return maxDepth(root.left) + 1;}int leftDepth = maxDepth(root.left);int rightDepth = maxDepth(root.right);return Math.max(leftDepth, rightDepth) + 1;}
}

559.N叉树的最大深度

给定一个N叉树,找到其最大深度。最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
输入:root = [1,null,3,2,4,null,5,6] 输出:3

思路:
如果根节点是 null,直接返回深度为 0;如果当前节点的 children 为空或 children.isEmpty() 为 true,说明它是叶子节点,深度为 1;遍历当前节点的所有子节点,递归计算每个子节点的深度。用 Math.max 维护所有子树的最大深度;当前节点的深度等于子树最大深度加 1。

java">class Solution {public int maxDepth(Node root) {if (root == null)   return 0;if(root.children == null || root.children.isEmpty())    return 1;    int maxDepth = 0;for (Node child : root.children) {maxDepth = Math.max(maxDepth, maxDepth(child));}return maxDepth + 1;}
}

111.二叉树的最小深度

给定一个二叉树root,返回其最大深度。二叉树的最小深度是指从根节点到最远叶子节点的最短路径上的节点数。
输入:root = [3,9,20,null,null,15,7] 输出:2

思路:
如果节点为空,深度为 0;如果左子树为空,递归计算右子树的深度;如果右子树为空,递归计算左子树的深度;如果左右子树都不为空,递归计算左右子树的深度。改为Math.min即可。


2 翻转二叉树

226.翻转二叉树

给你一棵二叉树的根节点root,翻转这棵二叉树,并返回其根节点。
输入:root = [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]

思路:
先序遍历,把输出改为交换节点的操作

java">class Solution {public TreeNode invertTree(TreeNode root) {if(root!=null){TreeNode temp=root.left;root.left=root.right;root.right=temp;invertTree(root.left);invertTree(root.right);}return root;}
}

3 对称二叉树

101.对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。
输入:root = [1,2,2,3,4,4,3] 输出:true

思路:
递归遍历

java">class Solution {public boolean isSymmetric(TreeNode root) {if (root == null) return true;return isSym(root.left, root.right);} public boolean isSym(TreeNode node1, TreeNode node2) {if (node1 == null && node2 == null) return true;if (node1 == null || node2 == null || node1.val != node2.val) {return false;}return isSym(node1.left, node2.right) && isSym(node1.right, node2.left);}
}

100.相同的树

给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
输入:p = [1,2,3], q = [1,2,3] 输出:true

思路:
递归遍历

java">class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {if(p==null&&q==null) return true;if(p==null||q==null) return false;if(p!=null&&q!=null&&q.val!=p.val) return false;return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);     }
}

572.另一棵树的子树

给你两棵二叉树root和subRoot。检验root中是否包含和subRoot具有相同结构和节点值的子树。如果存在,返回true;否则,返回false。二叉树tree的一棵子树包括tree的某个节点和这个节点的所有后代节点。tree也可以看做它自身的一棵子树。
输入:root = [3,4,5,1,2], subRoot = [4,1,2] 输出:true

思路:
如果subRoot为null,说明它是任何树的子树,直接返回true;如果root为null,说明主树为空,不可能包含子树,返回false。
如果当前节点值匹配(root.val==subRoot.val),则调用辅助函数isSameTree判断两棵树是否完全相同。如果当前节点值不匹配,递归判断subRoot是否为root.left或root.right的子树。

java">class Solution {public boolean isSubtree(TreeNode root, TreeNode subRoot) {if (subRoot == null) return true; if (root == null) return false; if (root.val == subRoot.val && isSameTree(root, subRoot)) {return true;}return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);}private boolean isSameTree(TreeNode p, TreeNode q) {if (p == null && q == null) return true;if (p == null || q == null) return false;if (p.val != q.val) return false;return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);}
}

4 完全二叉树的节点个数

222.完全二叉树的节点个数

给出一个完全二叉树,求出该树的节点个数。
输入:root = [1,2,3,4,5,6] 输出:6

思路:
递归遍历

java">class Solution {public int countNodes(TreeNode root) {if(root == null)    return 0;return countNodes(root.left) + countNodes(root.right) + 1;}
}

5 平衡二叉树

110.平衡二叉树

给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1。
输入:root = [3,9,20,null,null,15,7] 输出:true
思路:

Method1:全局变量

只有flag为true时才修改。否则不动flag,后序遍历求树高。

java">class Solution {boolean flag = true;public boolean isBalanced(TreeNode root) {findDepth(root);return flag;}public int findDepth(TreeNode root) {int hl, hr;if (root != null) {hl = findDepth(root.left);hr = findDepth(root.right);if (flag) {flag = Math.abs(hl - hr) <= 1;}return Math.max(hl, hr) + 1;} else {return 0;}}
}
Method2:快速返回

通过调用 findDepth 方法,如果返回值为 -1,表示树不平衡;否则树平衡,对于空节点,深度直接返回 0,递归计算左子树深度,如果左子树已经不平衡,直接返回 -1,终止后续计算(剪枝优化)。同样,递归计算右子树深度,提前剪枝。判断当前节点是否平衡,如果左右子树深度差超过 1,返回 -1。如果当前节点平衡,返回以该节点为根的子树的深度。

java">class Solution {public boolean isBalanced(TreeNode root) {return findDepth(root) != -1; }public int findDepth(TreeNode root) {if (root == null) return 0;int leftDepth = findDepth(root.left);if (leftDepth == -1) return -1;int rightDepth = findDepth(root.right);if (rightDepth == -1) return -1;if (Math.abs(leftDepth - rightDepth) > 1) return -1;return Math.max(leftDepth, rightDepth) + 1;}
}

6 二叉树的所有路径

257.二叉树的所有路径

给定一个二叉树,返回所有从根节点到叶子节点的路径。
输入:root = [3,9,20,null,null,15,7] 输出:true

思路:
回溯递归

java">class Solution {List<String> list = new ArrayList<>();public List<String> binaryTreePaths(TreeNode root) {if (root == null) {return list;}List<Integer> level = new ArrayList<>();level.add(root.val);dfs(root, level);return list;}public void dfs(TreeNode root, List<Integer> level) {if (root.left == null && root.right == null) {StringBuilder sb = new StringBuilder();for (Integer s : level) {sb.append(String.valueOf(s)).append("->");}if (sb.length() > 0) {sb.setLength(sb.length() - 2);}list.add(sb.toString());return;}if (root.left != null) {level.add(root.left.val);dfs(root.left, level);level.remove(level.size() - 1);}if (root.right != null) {level.add(root.right.val);dfs(root.right, level);level.remove(level.size() - 1);}return;}
}

7 左叶子之和

404.左叶子之和

计算给定二叉树的所有左叶子之和。
输入:root = [3,9,20,null,null,15,7] 输出:24

思路:
只有从左孩子分支进去的节点的左右孩子为空才将其值加入到sum中,否则继续遍历。

java">class Solution {int sum=0;public int sumOfLeftLeaves(TreeNode root) {if(root==null){return sum+0;}if(root.left!=null){sumOfLeftLeaves(root.left);if(root.left.left==null&&root.left.right==null){sum+=root.left.val;}}if(root.right!=null){sumOfLeftLeaves(root.right);}return sum;}
}

8 找树左下角的值

513.找树左下角的值

给定一个二叉树,在树的最后一行找到最左边的值。
输入: root = [2,1,3] 输出:1

思路:

Method1:递归法-先序遍历求二叉树高度

先遍历左子树,再遍历右子树,在遍历的过程中,如果更新了最大高度,那么一定是当前最左下的叶子节点

java">class Solution {private int Deep = -1;private int value = 0;public int findBottomLeftValue(TreeNode root) {value = root.val;findLeftValue(root,0);return value;}private void findLeftValue (TreeNode root,int deep) {if(root!=null){if(deep>Deep){Deep=deep;value=root.val;}findLeftValue(root.left,deep+1);findLeftValue(root.right,deep+1);}}
}
Method2:迭代层序遍历

迭代层序遍历,输出每层第一个

java">class Solution {public int findBottomLeftValue(TreeNode root) {Deque<TreeNode> queue = new ArrayDeque<>();queue.add(root);int res = 0;while (!queue.isEmpty()) {int size = queue.size();for (int i = 0; i < size; i++) {TreeNode poll = queue.poll();if (i == 0) res = poll.val;if (poll.left != null) {queue.add(poll.left);}if (poll.right != null) {queue.add(poll.right);}}}return res;}
}


http://www.ppmy.cn/server/164908.html

相关文章

ESP32(Arduino)

本篇内容在熟知51单片机与C语言基础上编写 一&#xff0c;开发板介绍和引脚图 USB接口用于下载程序&#xff0c;电源输入和烧录驱动等等。BOOT启动模式选择&#xff0c;按下为下载模式&#xff0c;放开为运行模式。ESP-32-WROOM-32模组集成了蓝牙&#xff0c;wifi等模块 共48…

【开源免费】基于SpringBoot+Vue.JS公交线路查询系统(JAVA毕业设计)

本文项目编号 T 164 &#xff0c;文末自助获取源码 \color{red}{T164&#xff0c;文末自助获取源码} T164&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

deepseek+vscode自动化测试脚本生成

近几日Deepseek大火,我这里也尝试了一下,确实很强。而目前vscode的AI toolkit插件也已经集成了deepseek R1,这里就介绍下在vscode中利用deepseek帮助我们完成自动化测试脚本的实践分享 安装AI ToolKit并启用Deepseek 微软官方提供了一个针对AI辅助的插件,也就是 AI Toolk…

处理 **5万字(约7.5万-10万token,中文1字≈1.5-2token)** 的上下文

处理 5万字&#xff08;约7.5万-10万token&#xff0c;中文1字≈1.5-2token&#xff09; 的上下文&#xff0c;对模型的长文本处理能力和显存要求较高。以下是不同规模模型的适用性分析及推荐&#xff1a; 一、模型规模与上下文能力的关系 模型类型参数量最大上下文长度&#…

FFmpeg(7.1版本)编译:Ubuntu18.04交叉编译到ARM

一、本地编译与交叉编译 1.本地编译 ① 本地编译:指的是在目标系统上进行编译的过程 , 生成的可执行文件和函数库只能在目标系统中使用。 如 : 在 Ubuntu中,本地编译的可执行文件只能在Ubuntu 系统中执行 , 无法在 Windows / Mac / Android / iOS 系统中使用 ; 在 Ubuntu…

【PyQt】getattr动态访问对象的属性

问题 使用qtdesigner设计好大体的软件结构&#xff0c;需要使用代码进行批量修改控件样式,self.ui.x 会被解释为访问 self.ui 中名为 x 的属性&#xff0c;而不是将 x 作为变量名来解析&#xff0c;此时需要通过字符串动态访问 self.ui 中的按钮对象 for i in range(20):x f…

Kafka架构

引言 Kafka 凭借其独树一帜的分区架构&#xff0c;在消息中间件领域展现出了卓越的性能表现。其分区架构不仅赋予了 Kafka 强大的并行计算能力&#xff0c;使其能够高效处理海量数据&#xff0c;还显著提升了系统的容灾能力&#xff0c;确保在复杂的运行环境中始终保持稳定可靠…

笔试-二进制

应用题 将符合区间[l,r]内的十进制整数转换为二进制表示&#xff0c;请问不包含“101”的整数个数是多少&#xff1f; 实现 l int(input("请输入下限l&#xff0c;其值大于等于1&#xff1a;")) r int(input("请输入上限r&#xff0c;其值大于等于l&#x…