Leetcode百题斩-二叉树

二叉树作为经典面试系列,那么当然要来看看。总计14道题,包含大量的简单题,说明这确实是个比较基础的专题。快速过快速过。

先构造一个二叉树数据结构。


public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) {this.val = val;}TreeNode(int val, TreeNode left, TreeNode right) {this.val = val;this.left = left;this.right = right;}public static TreeNode build(List<Integer> nodes) {if (nodes == null || nodes.isEmpty()) {return null;}List<TreeNode> treeList = new ArrayList<>();int nodePos = 0;int nodeLen = nodes.size();TreeNode root = new TreeNode(nodes.get(nodePos++));treeList.add(root);int treePos = 0;int treeLen = treeList.size();while (treePos < treeLen && nodePos < nodeLen) {TreeNode nowNode = treeList.get(treePos++);Integer nowVal = nodes.get(nodePos++);if (nowVal != null) {TreeNode leftNode = new TreeNode(nowVal);treeList.add(leftNode);nowNode.left = leftNode;}if (nodePos < nodeLen) {nowVal = nodes.get(nodePos++);if (nowVal != null) {TreeNode rightNode = new TreeNode(nowVal);treeList.add(rightNode);nowNode.right = rightNode;}}treeLen = treeList.size();}return root;}private List<Integer> levelOrderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();List<TreeNode> treeQueue = new ArrayList<>();if (root == null) {return Collections.emptyList();}treeQueue.add(root);int len = treeQueue.size();int pos = 0;int actualLen = len;while (pos < len) {for (int i = pos; i < len; i++) {TreeNode treeNode = treeQueue.get(i);if (treeNode == null) {if (i < actualLen) {result.add(null);}continue;}result.add(treeNode.val);treeQueue.add(treeNode.left);if (treeNode.left != null) {actualLen = treeQueue.size();}treeQueue.add(treeNode.right);if (treeNode.right != null) {actualLen = treeQueue.size();}len = treeQueue.size();}pos = len;}return result;}@Overridepublic String toString() {return levelOrderTraversal(this).toString();}
}

94. Binary Tree Inorder Traversal[Easy]

思路:中序遍历,没啥说的了,直接过

class Solution {public List<Integer> inorderTraversal(TreeNode root) {if (root == null) {return new ArrayList<>();}List<Integer> result = new ArrayList<>();result.addAll(inorderTraversal(root.left));result.add(root.val);result.addAll(inorderTraversal(root.right));return result;}
}

98. Validate Binary Search Tree[Medium]

思路:验证二叉搜索树, 完全可以用上面编号102题层序遍历上面编号94题中序遍历的代码,最后判断一下中序遍历的结果是否递增即可

class Solution {public boolean isValidBST(TreeNode root) {List<Integer> inorderTraversal = inorderTraversal(root);int len = inorderTraversal.size();for (int i = 1; i < len; i++) {if (inorderTraversal.get(i) <= inorderTraversal.get(i - 1)) {return false;}}return true;}
}

当然,用前一题的思路中序遍历一下,然后再用一个变量来记录当前遍历的数值,可以完成优化

class Solution {private Integer current;public boolean isValidBST(TreeNode root) {if (root.left != null && !isValidBST(root.left)) {return false;}if (current != null && current >= root.val) {return false;}current = root.val;if (root.right != null && !isValidBST(root.right)) {return false;}return true;}
}

101. Symmetric Tree[Easy]

思路:判断二叉树是否对称。最近写回溯写多了,不过这不是个回溯,这就是个正向递归,递归左右子树判断是否对称即可

class Solution {public boolean isSymmetric(TreeNode root) {if (root == null) {return true;}return isSymmetric(root.left, root.right);}public boolean isSymmetric(TreeNode leftTree, TreeNode rightTree) {if (leftTree == null && rightTree == null) {return true;}if (!(leftTree != null && rightTree != null)) {return false;}if (leftTree.val != rightTree.val) {return false;}if (!isSymmetric(leftTree.left, rightTree.right)) {return false;}if (!isSymmetric(leftTree.right, rightTree.left)) {return false;}return true;}
}

102. Binary Tree Level Order Traversal[Medium]

思路:二叉树层序遍历,没啥好说的,直接模拟队列即可

class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<TreeNode> treeQueue = new ArrayList<>();List<List<Integer>> result = new ArrayList<>();if (root == null) {return result;}treeQueue.add(root);int len = treeQueue.size();int pos = 0;while (pos < len) {List<Integer> levelResult = new ArrayList<>();for (int i = pos; i < len; i++) {TreeNode treeNode = treeQueue.get(i);levelResult.add(treeNode.val);if (treeNode.left != null) {treeQueue.add(treeNode.left);}if (treeNode.right != null) {treeQueue.add(treeNode.right);}}pos = len;len = treeQueue.size();result.add(levelResult);}return result;}
}

104. Maximum Depth of Binary Tree[Easy]

思路:求树的最大深度,这就是递归求左右子树最大深度然后对比即可,真一行代码搞定

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

105. Construct Binary Tree from Preorder and Inorder Traversal[Medium]

思路:根据前序遍历和中序遍历构造二叉树,这又是一道再经典不过的题了。前序遍历用于寻找父节点,推动遍历子树;中序遍历则用于划分左右子树。

class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {Map<Integer, Integer> inorderMap = new HashMap<>();int len = inorder.length;for (int i = 0; i < len; i++) {inorderMap.put(inorder[i], i);}return buildTree(preorder, inorder, 0, len, 0, len, inorderMap);}private TreeNode buildTree(int[] preorder, int[] inorder, int preStartPos, int preEndPos, int inStartPos,int inEndPos, Map<Integer, Integer> inorderMap) {int root = preorder[preStartPos];if (preStartPos == preEndPos) {return new TreeNode(root);}int inRootPos = inorderMap.get(root);int leftLen = inRootPos - inStartPos;TreeNode leftTree = buildTree(preorder, inorder, preStartPos + 1, preStartPos + leftLen, inStartPos, inRootPos,inorderMap);TreeNode rightTree = buildTree(preorder, inorder, preStartPos + leftLen + 1, preEndPos, inRootPos + 1, inEndPos,inorderMap);return new TreeNode(root, leftTree, rightTree);}
}

108. Convert Sorted Array to Binary Search Tree[Easy]

思路:别看easy题就放飞自我了。将有序数组转换为二叉搜索树,不仅保证树平衡,也要保证每个子树平衡,因此也要用到递归的

class Solution {public TreeNode sortedArrayToBST(int[] nums) {return sortedArrayToBST(nums, 0, nums.length);}private TreeNode sortedArrayToBST(int[] nums, int begin, int end) {if (begin >= end) {return null;}int mid = (begin + end) / 2;TreeNode root = new TreeNode(nums[mid]);TreeNode leftTree = sortedArrayToBST(nums, begin, mid);TreeNode rightTree = sortedArrayToBST(nums, mid + 1, end);root.left = leftTree;root.right = rightTree;return root;}
}

114. Flatten Binary Tree to Linked List[Medium]

思路:将二叉树压成链。这就涉及到二叉树断链和合链操作了。想清楚写个递归即可

class Solution {public void flatten(TreeNode root) {flattenTree(root);}private TreeNode flattenTree(TreeNode root) {if (root == null) {return null;}TreeNode leftTree = flattenTree(root.left);TreeNode rightTree = flattenTree(root.right);if (leftTree != null) {root.right = leftTree;root.left = null;if (rightTree != null) {while (leftTree.right != null) {leftTree = leftTree.right;}leftTree.right = rightTree;}}return root;}
}

199. Binary Tree Right Side View[Medium]

思路:求二叉树的右视图,这个就完全可以用上面编号102题层序遍历的代码,然后取每层最后一个即可

class Solution {public List<Integer> rightSideView(TreeNode root) {List<List<Integer>> levelOrder = levelOrder(root);return levelOrder.stream().map(list -> list.get(list.size() - 1)).collect(Collectors.toList());}
}

当然,也可以将层序遍历的代码拿来优化一下,不需要记录层序遍历多余的节点,只需要记录每层末节点即可

class Solution {public List<Integer> rightSideView(TreeNode root) {List<TreeNode> treeQueue = new ArrayList<>();List<Integer> result = new ArrayList<>();if (root == null) {return Collections.emptyList();}treeQueue.add(root);int len = treeQueue.size();int pos = 0;while (pos < len) {int lastNode = root.val;for (int i = pos; i < len; i++) {TreeNode treeNode = treeQueue.get(i);lastNode = treeNode.val;if (treeNode.left != null) {treeQueue.add(treeNode.left);}if (treeNode.right != null) {treeQueue.add(treeNode.right);}}pos = len;len = treeQueue.size();result.add(lastNode);}return result;}
}

230. Kth Smallest Element in a BST[Medium]

思路:求二叉搜索树的第k小值,又可以用到上面编号94题中序遍历的代码,然后取遍历数组中的第k个即可

class Solution {public int kthSmallest(TreeNode root, int k) {List<Integer> inorderTraversal = inorderTraversal(root);return inorderTraversal.get(k - 1);}
}

当然,与上一题同样的原理,优化一下,用一个变量来记录一下当前遍历到的位置,这样就可以在搜索到结果的时候提前结束,降低时耗

class Solution {private int now = 1;public int kthSmallest(TreeNode root, int k) {if (root == null) {return -1;}int leftValue = kthSmallest(root.left, k);if (leftValue != -1) {return leftValue;}if (now == k) {return root.val;}now++;return kthSmallest(root.right, k);}
}

437. Path Sum III[Medium]

思路:求二叉树中路径和为特定树的路径个数。这一题有一点点树上DP的感觉,每个节点分别往左右子树上递归,分为计算该节点和不计算该结点进行转移。最后注意一个小细节,就是要注意边界问题,多个数的和是很可能超int边界的,注意要开成long

class Solution {public int pathSum(TreeNode root, int targetSum) {return pathSum(root, targetSum, true) + pathSum(root, targetSum, false);}private int pathSum(TreeNode root, long targetSum, boolean include) {int count = 0;if (root == null) {return count;}if (include) {if (root.val == targetSum) {count++;}count += pathSum(root.left, targetSum - root.val, true);count += pathSum(root.right, targetSum - root.val, true);} else {count += pathSum(root.left, targetSum, true);count += pathSum(root.right, targetSum, true);count += pathSum(root.left, targetSum, false);count += pathSum(root.right, targetSum, false);}return count;}
}

求和问题,当然再来一套前缀和。经典的字符串前缀和可以看我之前的哈希系列

class Solution {public int pathSum(TreeNode root, int targetSum) {HashMap<Long, Integer> sumMap = new HashMap<>();sumMap.put(0L, 1);return preSumPre(root, targetSum, sumMap, 0);}private int preSumPre(TreeNode root, int targetSum, Map<Long, Integer> sumMap, long currentSum) {int count = 0;if (root == null) {return count;}currentSum += root.val;if (sumMap.containsKey(currentSum - targetSum)) {count += sumMap.get(currentSum - targetSum);}sumMap.put(currentSum, sumMap.getOrDefault(currentSum, 0) + 1);count += preSumPre(root.left, targetSum, sumMap, currentSum);count += preSumPre(root.right, targetSum, sumMap, currentSum);sumMap.put(currentSum, sumMap.getOrDefault(currentSum, 0) - 1);return count;}
}

543. Diameter of Binary Tree[Easy]

思路:求二叉树最长路径。首先要递归求每个子树的最长路径,即等于左右子树的高度和。递归函数将子树高度返回,用一个单独的变量记录当前最长路径并在每个子树内比较更新即可

class Solution {private int maxLength = 0;public int diameterOfBinaryTree(TreeNode root) {getLength(root);return maxLength;}private int getLength(TreeNode root) {if (root == null) {return 0;}int leftLength = getLength(root.left);int rightLength = getLength(root.right);if (leftLength + rightLength > maxLength) {maxLength = leftLength + rightLength;}return Math.max(leftLength, rightLength) + 1;}
}

236. Lowest Common Ancestor of a Binary Tree[Medium]

这就是前两天刚做过的通义app面试题,关于LCA的问题我专门特地整理了一下,感兴趣可以前去看看:

最近公共祖先(LCA)

226. Invert Binary Tree[Easy]

偶然发现,这题我在五年前校招刷题的时候也写过,当时的链接:二叉树翻转链接

左右子树递归交换一下即可

class Solution {public TreeNode invertTree(TreeNode root) {if (root == null) {return null;}TreeNode left = invertTree(root.left);TreeNode right = invertTree(root.right);root.left = right;root.right = left;return root;}
}

再来看一下当时我这题,我把他和另两道链表的题总结在了一起,刚好这个二叉树专题就要结束了,顺便预告温习一下百题斩的下一个专题,就是链表专题

最后,完结撒花,下个专题再见

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

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

相关文章

Asp.Net Core 如何配置在Swagger中带JWT报文头

文章目录 前言一、配置方法二、使用1、运行应用程序并导航到 /swagger2、点击右上角的 Authorize 按钮。3、输入 JWT 令牌&#xff0c;格式为 Bearer your_jwt_token。4、后续请求将自动携带 Authorization 头。 三、注意事项总结 前言 配置Swagger支持JWT 一、配置方法 在 …

MySQL 定时逻辑备份

文章目录 配置密码编写备份脚本配置权限定时任务配置检查效果如果不想保留明文密码手工配置备份密码修改备份命令 配置密码 cat >> /root/.my.cnf <<"EOF" [client] userroot passwordYourPassword EOF编写备份脚本 cat > /usr/local/bin/mysql_dum…

在qt中使用c++实现与Twincat3 PLC变量通信

这是一个只针对新手的教程&#xff0c;下载安装就不说了&#xff0c;我下的是TC31-Full-Setup.3.1.4024.66.exe是这个版本&#xff0c;其他版本应该问题不大。 先创建一个项目 选中SYSTEM&#xff0c;在右侧点击Choose Target&#xff08;接下来界面跟我不一样没关系&#xf…

云原生微服务devops项目管理英文表述详解

文章目录 1.云原生CNCF trail map云原生技术栈路线图 2. 微服务单体应用与微服务应用架构区别GraphQLKey differences: GraphQL and REST 3.容器化&编排dockerKubernetesContainers and ContainerizationContainer Basics 4. DevOps & CI/CDTerms and Definitions 5.Ag…

pyside 使用pyinstaller导出exe(含ui文件)

第一步&#xff1a;首先确保安装好pyinstall&#xff0c;终端运行 pyinstaller -w main.py 生成两个文件夹 打开exe文件报错&#xff0c;问题是ui文件找不到 第二步&#xff1a;将ui文件复制到exe所在文件夹&#xff0c;打开成功 ![在这里插入图片描述](https://i-blog.csdni…

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器

kerberos在无痕浏览器 获取用户信息失败 如何判断是否无痕浏览器 js 代码 其他地方用直接导入js getCurrentUserId 这是自己后端获取 域账号地址 我是成功返回200 //true普通浏览器 fasle 无痕浏览器 export const checkBrowserMode async () > {try {const response a…

HTML 计算网页的PPI

HTML 计算网页的PPI vscode上安装live server插件&#xff0c;可以实时看网页预览 有个疑问&#xff1a; 鸿蒙density是按照类别写死的吗&#xff0c;手机520dpi 折叠屏426dpi 平板360dpi <html lang"en" data - overlayscrollbars - initialize><header&…

华为OD机试真题——Boss的收入(分销网络提成计算)(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

<el-date-picker>组件传参时,选中时间和传参偏差8小时

遇到一个bug&#xff0c;不仔细看&#xff0c;都不一定能发现&#xff0c;bug描述&#xff1a;我们有一个搜索框&#xff0c;里面有一个时间选择器&#xff0c;当我使用<el-date-picker>时&#xff0c;我发现当我选择时分秒之后&#xff0c;显示都正常&#xff0c;但是当…

uni-app开发特殊社交APP

uni-app开发特殊社交APP 目录 1.展示APP功能 2.展示项目结构 3.关于我的GitHub 引言 博主最近自己在GitHub上面上传了一个关于社交软件的项目&#xff08;该项目早已开发完毕&#xff09;, 这个社交软件比较特殊, 被称之为blind-date&#xff0c; blind-date 是基于 uni-…

深入研究Azure 容器网络接口 (CNI) overlay

启用cni overlay 在通过portal创建aks的时候,在networking配置上,选中下面的选项即可启用。 通过CLI创建AKS 要创建具有 CNI 覆盖网络的 AKS 群集,需要在创建群集时指定 --network-plugin azure 和 --network-plugin-mode 覆盖选项。 还需要指定 --pod-cidr 选项来定义群…

Docker 部署项目

使用 Docker 部署项目是一个很好的选择&#xff0c;可以避免服务器环境不兼容的问题&#xff0c;并且能够实现一致性和可移植性。我会给你一个详细的步骤&#xff0c;帮你从零开始理解 Docker&#xff0c;最终在服务器上部署 Roop 项目。 1. 安装 Docker 首先&#xff0c;你需…

excel表格记账 : 操作单元格进行加减乘除 | Excel中Evaluate函数

文章目录 引用I 基础求和∑II Excel中Evaluate函数基于字符串表达式进行计算用法案例 :基于Evaluate实现汇率计算利润知识扩展在单元格内的换行选择整列单元格引用 需求: 基于汇率计算利润,调整金额以及进汇率和出汇率自动算出利润,已经统计总利润。 基于Evaluate实现汇率计…

vue+ts+TinyEditor 是基于 Quill 2.0 开发的富文本编辑器,提供丰富的扩展功能,适用于现代 Web 开发的完整安装使用教程

简介 TinyEditor 是基于 Quill 2.0 开发的富文本编辑器&#xff0c;提供丰富的扩展功能&#xff0c;适用于现代 Web 开发。具备模块化设计、轻量级架构和高度可定制化特性&#xff0c;支持多种插件扩展&#xff0c;满足不同场景需求。 核心特性 基于 Quill 2.0 的现代化架构模…

matlab实现激光腔长计算满足热透镜效应

激光腔长计算与热透镜效应补偿 在全固态激光器中&#xff0c;热透镜效应是一个重要的问题&#xff0c;因为它会影响激光的光束质量和输出功率。以下是如何计算激光腔长并考虑热透镜效应的方法&#xff0c;以及一些补偿技术。 1. 激光腔长计算 激光腔长的计算需要考虑激光晶体…

Science Robotics 具身智能驱动的空中物理交互新范式:结合形态和传感,与非结构化环境进行稳健交互

随着科技的飞速发展&#xff0c;无人机技术已从单纯的远程感知扩展到与环境的物理交互领域&#xff0c;为可持续发展目标的实现提供了新的可能性。传统的空中物理交互方法依赖于复杂的控制策略和精确的环境建模&#xff0c;尽管能够实现高精度操作&#xff0c;但其在非结构化自…

图神经网络在信息检索重排序中的应用:原理、架构与Python代码解析

现代信息检索系统和搜索引擎普遍采用两阶段检索架构&#xff0c;在人工智能应用中也被称为检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;。在初始检索阶段&#xff0c;系统采用高效的检索方法&#xff0c;包括词汇检索算法&#xff08;如BM25&…

List 源码翻译

List 源码翻译-jdk1.8 翻译来自 AI 大模型。 全部源码翻译下载 /** 版权所有 (c) 1997, 2014, Oracle 和/或其附属公司。保留所有权利。* ORACLE 专有/机密。使用受许可条款约束。*********************/package java.util;import java.util.function.UnaryOperator;/*** 有序…

Vscode 解决 #include <> 找不到的问题

本人遇到的情况, 使用 ROS 的过程中, 发现 #include <pcl/point_types.h> 不被 VScode 识别, 在 AI 的帮助下解决了该问题, 现总结如下: 1. 查看是否有相应的文件 Linux 下, point_types.h 的存储路径一般为: /usr/include/pcl-1.x (我的路径是 /usr/include/pcl-1.12)…