2025高频面试算法总结篇【二叉树】

文章目录

  • 直接刷题链接直达
  • 非递归实现求二叉树的深度
  • 非递归从左至右打印一颗二叉树中的所有路径
  • 判断平衡二叉树
  • 二叉搜索树中第K小的元素
  • 二叉树的完全性检验
  • 根据前&中序遍历结果重建二叉树
  • 二叉树的最近公共祖先
  • 二叉树的直径
  • 二叉树的遍历


直接刷题链接直达

  • 非递归实现求二叉树的深度
    • 引入队列,统计当前层次节点数目,逐层遍历
    • 二叉树的深度(递归和非递归)
    • 102. 二叉树的层次遍历
  • 非递归从左至右打印一颗二叉树中的所有路径
    • 257. 二叉树的所有路径
  • 判断平衡二叉树
    • 110. 平衡二叉树
  • 寻找二叉搜索树中第一个大于k的节点
    • 中序遍历求值
    • 类似于 230. 二叉搜索树中第K小的元素
  • 二叉树的完全性检验
    • 958. 二叉树的完全性检验
  • 根据前&中序遍历结果重建二叉树
    • 首先找到根节点,再划分左右子树区域,逐层递归找到左右子节点
    • 105. 从前序与中序遍历序列构造二叉树
  • 实现一个二叉搜索树迭代器,包括 next() hasNext() 方法(PayPal)
    • 173. 二叉搜索树迭代器
  • 二叉树的右视图(Shopee)
    • 199. 二叉树的右视图
  • 给定一个二叉树根节点和指定路径,判断二叉树中是否存在给定指定路径,且要求指定路径最后一个元素为叶节点
  • 将一颗二叉搜索树转化成一个排序的双向链表
    • 不能创建新结点
    • 二叉搜索树与双向链表
  • 二叉树的最近公共祖先
    • 首先判断当前节点是否为指定结点,是则返回
    • 递归当前结点的左右子树
    • 如果两边均不为null,表示找到,返回当前结点,均为null则返回null,否则返回对应子节点(left / right)
    • 236. 二叉树的最近公共祖先
    • Lowest Common Ancestor Binary Tree(各种情况详细举例,推荐)
  • 二叉树的中序遍历的下一个结点
    • 先判断右子结点不为空,返回右子节点最左边的节点
    • 若父节点不为空,上溯到根节点的 “/”即返回
    • 二叉树的下一个结点
  • 红黑树描述及其复杂度分析(插入/查找)
    • 查找、插入、删除时间复杂度 --> O(logN)
    • 红黑树 Wiki
    • 26 | 红黑树(下):掌握这些技巧,你也可以实现一个红黑树 (红黑树分析)
  • 二叉树的直径
    • 543. 二叉树的直径
  • 二叉树的遍历
    • 二叉树的前序遍历 / 二叉树的中序遍历 / 二叉树的后序遍历

非递归实现求二叉树的深度

题目: 给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

递归:

class Solution {public int maxDepth(TreeNode root) {if (root == null) return 0;int left = maxDepth(root.left);int right = maxDepth(root.right);return (left > right ? left:right) +1;}
}

非递归:
引入队列,统计当前层次节点数目,逐层遍历

class Solution {public int maxDepth(TreeNode root) {if (root == null) return 0;Queue<TreeNode> q = new LinkedList<>();q.offer(root);int depth = 0;while (!q.isEmpty()) {depth++;int total = q.size(); // 统计这层的数量=》全部出队列,然后他们的子节点入队while (total-- > 0) {TreeNode temp = q.poll();if (temp.left != null) {q.offer(temp.left);}if (temp.right != null) {q.offer(temp.right);}}}return depth;}
}

非递归从左至右打印一颗二叉树中的所有路径

题目: 给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

递归:

class Solution {public List<String> binaryTreePaths(TreeNode root) {treePath(root, "");return res;}List<String> res = new ArrayList<>();public void treePath(TreeNode root, String path) {if (root == null) {return;}// 叶子节点if (root.left == null && root.right == null) {res.add(path+root.val);return;}treePath(root.left, path+root.val+"->");treePath(root.right, path+root.val+"->");}
}

非递归:

class Solution {// 257. 二叉树的所有路径public List<String> binaryTreePaths(TreeNode root) {List<String> res = new LinkedList<>();if (root == null) return res;// 存放 节点Stack<TreeNode> nodeStack = new Stack<>();// 存放 pathStack<String> pathStack = new Stack<>();// 根节点 入栈nodeStack.push(root);pathStack.push(root.val + "");while (!nodeStack.isEmpty()) {TreeNode node = nodeStack.pop();String path = pathStack.pop();if (node.left == null && node.right == null) {res.add(path);}if (node.right != null) {pathStack.push(path + "->" + node.right.val);nodeStack.push(node.right);}if (node.left != null) {pathStack.push(path + "->" + node.left.val);nodeStack.push(node.left);}}return res;}
}

判断平衡二叉树

题目:给定一个二叉树,判断它是否是 平衡二叉树

class Solution {public boolean isBalanced(TreeNode root) {if (root == null) return true;if(Math.abs(findDepth(root.left)-findDepth(root.right)) > 1) return false;return isBalanced(root.left) && isBalanced(root.right);}public int findDepth(TreeNode root) {if (root == null) return 0;int left = findDepth(root.left);int right = findDepth(root.right);return (left > right ? left:right)+1;}
}

二叉搜索树中第K小的元素

题目: 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从 1 开始计数)。

class Solution {List<Integer> list;public int kthSmallest(TreeNode root, int k) {list = new ArrayList<>();inOrder(root);return list.get(k-1);}public void inOrder(TreeNode root) {if (root == null) return;inOrder(root.left);list.add(root.val);inOrder(root.right);}}

二叉树的完全性检验

题目: 给你一棵二叉树的根节点 root ,请你判断这棵树是否是一棵 完全二叉树 。

对于一个完全二叉树,层序遍历的过程中遇到第一个空节点之后不应该再出现非空节点


class Solution {public boolean isCompleteTree(TreeNode root) {if (root == null) return true;// 层次遍历Queue<TreeNode> q = new LinkedList<>();q.offer(root);boolean flag = false; // 开始出现 null 节点while(!q.isEmpty()) {TreeNode t = q.poll();if (flag && t != null) {return false;}if (t == null) {flag = true;}else {q.offer(t.left);q.offer(t.right);}}return true;}
}

根据前&中序遍历结果重建二叉树

题目:给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

class Solution {private HashMap<Integer, Integer> inorderMap; // 存放中序值和索引private int preorderIndex = 0;// 当前访问的前序的位置public TreeNode buildTree(int[] preorder, int[] inorder) {inorderMap = new HashMap<>();for (int i = 0; i < inorder.length; i++) {inorderMap.put(inorder[i], i);}return createTree(preorder, 0, inorder.length-1);}public TreeNode createTree(int[] preorder, int left, int right) {if (left > right) return null;int val = preorder[preorderIndex++];TreeNode root = new TreeNode(val);root.left = createTree(preorder, left, inorderMap.get(val)-1);root.right = createTree(preorder, inorderMap.get(val)+1, right);return root;}
}

二叉树的最近公共祖先

题目: 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if (root == null || p == root || q == root) return root;TreeNode left = lowestCommonAncestor(root.left, p, q);TreeNode right = lowestCommonAncestor(root.right, p, q);if (left != null && right != null) return root;return left != null ? left:right;}
}

二叉树的直径

给你一棵二叉树的根节点,返回该树的 直径 。

二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。

两节点之间路径的 长度 由它们之间边数表示。

class Solution {// 543 二叉树的直径private int maxDiameter = 0;public int diameterOfBinaryTree(TreeNode root) {maxDepth(root); // 在计算深度的过程中更新最大直径return maxDiameter;}// 计算树的最大深度,同时更新最大直径private int maxDepth(TreeNode node) {if (node == null) {return 0;}int left = maxDepth(node.left); // 左子树深度int right = maxDepth(node.right); // 右子树深度// 更新直径:左子树深度 + 右子树深度maxDiameter = Math.max(maxDiameter, left + right);// 返回当前节点的深度return Math.max(left, right) + 1;}}

二叉树的遍历

前序遍历:

class Solution {public List<Integer> preorderTraversal(TreeNode root) {preorder(root);return ans;}List<Integer> ans = new ArrayList<>();public void preorder(TreeNode root) {if (root == null) return;ans.add(root.val);preorder(root.left);preorder(root.right);}
}

中序遍历:

class Solution {// 92 中序遍历public List<Integer> inorderTraversal(TreeNode root) {inorder(root);return ans;}List<Integer> ans = new ArrayList<>();public void inorder(TreeNode root) {if (root == null) return;inorder(root.left);ans.add(root.val);inorder(root.right);}
}

后续遍历:

class Solution {public List<Integer> postorderTraversal(TreeNode root) {postorder(root);return ans;}List<Integer> ans = new ArrayList<>();public void postorder(TreeNode root) {if (root == null) return;postorder(root.left);postorder(root.right);ans.add(root.val);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/900565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis 和 MongoDB都可以存储键值对,并且值可以是复杂json,用完整例子分别展示说明两者在存储json键值对上的使用对比

Redis 存储 JSON 键值对示例 存储操作&#xff1a; // 存储用户信息&#xff08;键&#xff1a;user:1001&#xff0c;值&#xff1a;JSON对象&#xff09; SET user:1001 {"name":"Alice", "age":30, "address":"New York&quo…

介绍几种创意登录页(含完整源码)

今天为大家收集了几种不同风格的登录页&#xff0c;搭配动态渐变背景&#xff0c;效果绝对惊艳&#xff01; CSS3实现动态渐变玻璃拟态登录页 一、开篇语 纯CSS实现当下最火的玻璃拟态(Morphism)风格登录页&#xff0c;搭配动态渐变背景&#xff0c;效果绝对惊艳&#xff01; …

R语言之mlr依赖包缺失警告之分析

因为本地没有网络&#xff0c;所有相关的依赖包都是手动下载&#xff0c;再使用脚本一键安装的。 在使用mlr包时&#xff0c;执行下面的代码时&#xff0c;总是报各种依赖缺失&#xff0c;也不知道咋看FAIL信息。 # 建模与调参 # 查阅线性回归、随机森林、xgboost和KNN四种模…

无状态版的DHCPv6是不是SLAAC? 笔记250405

无状态版的DHCPv6是不是SLAAC? 笔记250405 无状态版 DHCPv6 不是 SLAAC&#xff0c;但二者在 IPv6 网络中可协同工作。以下是核心区别与协作关系&#xff1a; 本质区别 特性SLAAC无状态 DHCPv6主要功能生成 IPv6 地址&#xff08;基于路由器通告的前缀&#xff09;分发 DNS、…

uniapp微信小程序地图marker自定义气泡 customCallout偶尔显示不全解决办法

这个天坑问题&#xff0c;在微信开发工具上是不会显示出来的,只有在真机上才会偶尔出现随机样式偏移/裁剪/宽长偏移&#xff0c;询问社区也只是让你提交代码片段&#xff0c;并无解决办法。 一开始我怀疑是地图组件加载出现了问题&#xff0c;于是给地图加了一个v-if"reL…

LabVIEW商业软件开发注意问题

在 LabVIEW 商业软件开发进程中&#xff0c;性能优化、界面设计及兼容性与扩展性&#xff0c;对软件品质、用户体验和市场适配性起着决定性作用。下面&#xff0c;借助多个LabVIEW 编程特性的实际案例&#xff0c;深入分析这些方面的开发要点。 一、性能优化&#xff1a;提升软…

Ubuntu 安装 VLC

最近项目中需要用VLC查看NVR下子设备的RTSP流&#xff0c;特此记录&#xff0c;便于日后查阅。 1、安装snap $ sudo apt update $ sudo apt install snapd 2、安装vlc $ sudo snap install vlc 3、可能遇到的问题 snap beta install on ubuntu 22.04 failing to start Qt: Se…

LeetCode 3047 求交集区域内的最大正方形面积

探寻矩形交集中的最大正方形面积 在算法与数据结构的探索之路上&#xff0c;二维平面几何问题一直占据着独特的地位&#xff0c;它们不仅考验我们的空间思维能力&#xff0c;还要求我们能够巧妙地运用算法逻辑。今天&#xff0c;我们将深入剖析一道极具代表性的二维平面几何算…

【Kafka基础】Kafka 2.8以下版本的安装与配置指南:传统ZooKeeper依赖版详解

对于仍在使用Kafka 2.8之前版本的团队来说&#xff0c;需要特别注意其强依赖外部ZooKeeper的特性。本文将完整演示传统架构下的安装流程&#xff0c;并对比新旧版本差异。 1 版本特性差异说明 1.1 2.8 vs 2.8-核心区别 特性 2.8版本 2.8-版本 协调服务 可选内置KRaft模式 …

springboot+easyexcel实现下载excels模板下拉选择

定义下拉注解 Target(ElementType.FIELD) Retention(RetentionPolicy.RUNTIME) public interface ExcelDropDown {/*** 固定下拉选项*/String[] source() default {};/*** 动态数据源key&#xff08;从上下文中获取&#xff09;*/String sourceMethod() default "";…

第15周:注意力汇聚:Nadaraya-Watson 核回归

注意力汇聚&#xff1a;Nadaraya-Watson 核回归 Nadaraya-Watson 核回归是一个经典的注意力机制模型&#xff0c;它展示了如何通过注意力权重来对输入数据进行加权平均。以下是该内容的核心总结&#xff1a; 关键概念 注意力机制框架&#xff1a;由查询&#xff08;自主提示…

adb devices报错 ADB server didn‘t ACK

ubuntu下连接手机首次使用adb devices 报错ADB server didn’t ACK adb devices * daemon not running; starting now at tcp:5037 ADB server didnt ACK Full server startup log: /tmp/adb.1000.log Server had pid: 52986 --- adb starting (pid 52986) --- 04-03 17:23:23…

Mac下Homebrew的安装与使用

Mac下Homebrew的安装与使用 一蓑烟羽 关注 2017.10.19 11:59* 字数 515 阅读 7684评论 0喜欢 3 Homebrew简介&#xff0c;安装与使用 简介 Homebrew 官方网站 Homebrew是一个包管理器&#xff0c;用于安装Apple没有预装但你需要的UNIX工具。&#xff08;比如著名的wget&am…

非常适合做后台项目的go脚手架

分享一个非常适合做后台脚手架的go项目&#xff0c;该项目使用gin作为mvc框架搭建。她就是Gin-vue-admin。该一个基于 vue 和 gin 开发的全栈前后端分离的开发基础平台&#xff0c;集成jwt鉴权&#xff0c;动态路由&#xff0c;动态菜单&#xff0c;casbin鉴权&#xff0c;表单…

优化 Django 数据库查询

优化 Django 数据库查询 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 优化 Django 数据库查询**理解 N+1 查询问题****`select_related`:外键的急加载**示例何时使用 `select_re…

大数据(5)Spark部署核弹级避坑指南:从高并发集群调优到源码级安全加固(附万亿级日志分析实战+智能运维巡检系统)

目录 背景一、Spark核心架构拆解1. 分布式计算五层模型 二、五步军工级部署阶段1&#xff1a;环境核弹级校验阶段2&#xff1a;集群拓扑构建阶段3&#xff1a;黄金配置模板阶段4&#xff1a;高可用启停阶段5&#xff1a;安全加固方案 三、万亿级日志分析实战1. 案例背景&#x…

【学Rust写CAD】36 颜色插值函数(alpha256.rs补充方法)

源码 pub fn alpha_lerp(self,src: Argb, dst: Argb, clip: u32) -> Argb {self.alpha_mul_256(clip).lerp(src, dst)}这个函数 alpha_lerp 是一个颜色插值&#xff08;线性插值&#xff0c;lerp&#xff09;函数&#xff0c;它结合了透明度混合&#xff08;alpha_mul_256&…

解决Ubuntu系统鼠标不流畅的问题

电脑是联想的台式组装机&#xff0c;安装ubuntu系统&#xff08;不管是16、18、20、22&#xff09;后&#xff0c;鼠标都不流畅。最近几天想解决这个问题&#xff0c;于是怀疑到了显卡驱动上。怀疑之前一直用的是集成显卡&#xff0c;而不是独立显卡&#xff0c;毕竟2060的显卡…

oracle asm 相关命令和查询视图

有关asm磁盘的命令 添加磁盘 alter diskgroup data1 add disk /devices/diska*;---runs with a rebalance power of 5 , and dose not return until the rebalance operation is completealter diskgroup data1 add disk /devices/diskd* rebalance power 5 wait;查询 select …

C++基于rapidjson的Json与结构体互相转换

简介 使用rapidjson库进行封装&#xff0c;实现了使用C对结构体数据和json字符串进行互相转换的功能。最短只需要使用两行代码即可无痛完成结构体数据转换为Json字符串。 支持std::string、数组、POD数据&#xff08;int,float,double等&#xff09;、std::vector、嵌套结构体…