“手撕”二叉树的OJ习题
故事的开头,我们先来三道不是oj的开胃菜,练练手感,后面9道都是OJ题。
目录
第一题
第二题
第三题
第四题
第五题
第六题
第七题
第八题
第九题
第十题
第十一题
第一题
二叉树前序非递归遍历实现 。
首先我们需要一个栈来存放二叉树里面的元素,定义一个Tree Node类型的cur来指向要入栈的元素,然后一直往栈里放root.left,边放边打印,全部放完就出栈。最后让cur指向栈顶元素,也就是回退到不为空的节点,再遍历right。!stack.isEmpty()就是栈里面不为空,就不用再写一遍while的打印循环了。
public void preOrderNot(TreeNode root) {Stack<TreeNode> stack = new Stack<>();if (root == null) {return;}TreeNode cur = root;while (cur != null || !stack.isEmpty()) {while (cur != null) {stack.push(cur);System.out.print(cur.val + " ");cur = cur.left;}TreeNode top = stack.pop();cur = top.right;}}
第二题
二叉树中序非递归遍历实现。
这也是同上面那一道题一样,但是要注意的就是,要先遍历完全部的left再打印,而前序遍历是边遍历边打印。
public void inOrderNot(TreeNode root) {Stack<TreeNode> stack = new Stack<>();if (root == null) return;TreeNode cur = root;while (cur != null || !stack.isEmpty()) {while (cur != null) {stack.push(cur);cur = cur.left;}TreeNode top = stack.pop();System.out.print(top.val + " ");cur = top.right;}}
第三题
二叉树后序非递归遍历实现。
这道题稍微会比上面两道复杂一点,但是大致思路也是一样的。如果完全按照上面两道题的思路就会陷入死循环。这里遇到空,栈顶top不能直接pop,需要peek看一下 ,因为一删就没有了,找不到了,后序遍历还没有打印这个节点,得左右都打印完才能打印。所以需要看看right有没有元素。跟着代码就会死循环,所以需要定义一个prev表示如果打印过了,就不再循环,退回上一个元素,就不会死循环了。
public void postOrderNot(TreeNode root) {Stack<TreeNode> stack = new Stack<>();if (root == null) {return;}TreeNode cur = root;TreeNode prev=null;while (cur != null || !stack.isEmpty()) {while (cur != null) {stack.push(cur);cur = cur.left;}TreeNode top = stack.peek();//第二个条件说明被打印过了,直接弹出他的父亲并打印if (top.right == null||prev==top.right) {stack.pop();System.out.print(top.val + " ");prev=top;} else {cur = top.right;}}}
第四题
检查两颗树是否相同。 OJ链接
这道题非常简单,从结构上开始考虑,如果两个为空,为true;一个为空一个不为空,结构长得都不一样所以false,两个都不为空,这时候才开始判断他们的值一不一样,不一样false,一样的话继续递归。
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) {return false;}//两个都不为空,开始比较if (p.val != q.val) {return false;}return isSameTree(p.left, q.left) &&isSameTree(p.right, q.right);}
第五题
另一颗树的子树。OJ链接
也是通过结构判断,要判断的树为空直接false;从最初的根开始就一样了, true;左子树和子树一样,true;右子树一样也是true;不然就是false。
public boolean isSubtree(TreeNode root, TreeNode subRoot) {if(root==null){return false;}if(isSameTree(root,subRoot)){return true;}if(isSubtree(root.left,subRoot)){return true;}if(isSubtree(root.right,subRoot)){return true;}return false;}
第六题
翻转二叉树。OJ链接
树为空,不能翻转,返回null 。定义一个tmp来作为中间媒介交换左和右的元素,由于父亲被带过去了,所以孩子也会一整个被搬过去,不用担心递归时子类的左右树不匹配。然后再把左子树和右子树都进行递归,最后返回根节点。
public TreeNode invertTree(TreeNode root) {if(root==null){return null;}TreeNode tmp=root.left;root.left=root.right;root.right=tmp;invertTree(root.left);invertTree(root.right);return root;}
第七题
判断一颗二叉树是否是平衡二叉树。OJ链接
什么是平衡二叉树?就是左子树和右子树高度差必须小于等于1。左子树如果树为空,平衡true;定义左高度和右高度,用getHeight方法获取左右树的高度,然后用绝对值方法abs来求高度差,只要左子树和右子树高度差小于1,并且左子树自己平衡,右子树也平衡才true。
public boolean isBalanced(TreeNode root) {if(root==null){return true;}int leftH=getHeight(root.left);int rightH=getHeight(root.right);return Math.abs(leftH-rightH)<=1&&isBalanced(root.left)&&isBalanced(root.right);}// 获取二叉树的高度public int getHeight(TreeNode root) {if(root==null){return 0;}int leftH=getHeight(root.left);int rightH=getHeight(root.right);return Math.max(leftH,rightH)+1;}
第八题
对称二叉树。 OJ链接
如果root==null则是true,书写一个检测子树对不对称的方法,然后判断结构,如果左子树为空,右子树不为空,或者右子树为空,左子树不为空,则结构不同,false;如果两个都为空,则返回true;如果两个都不为空,则判断他们的值,不一样就false,一样的话就继续递归。
public boolean isSymmetric(TreeNode root) {if (root == null) {return true;}return isSymmetricchild(root.left, root.right);}public boolean isSymmetricchild(TreeNode leftTree, TreeNode rightTree) {if (leftTree != null && rightTree == null || leftTree == null && rightTree != null) {return false;}if (leftTree == null && rightTree == null) {return true;}if (leftTree.val != rightTree.val) {return false;}return isSymmetricchild(leftTree.left, rightTree.right) &&isSymmetricchild(leftTree.right, rightTree.left);}
第九题
二叉树的构建及遍历。OJ链接
利用i++,遍历一个字符串,charAt获取每个元素,如果不为“#”则直接new TreeNode(charAt(i))进去接到root后面,是的话就i++;问题来了,new了不就重新创建TreeNode了吗,不会把之前的替换掉吗?不会,因为需要在后面的代码写上root.leftheroot.right递归下去,new出来的root直接接到left和right上面了。
class TreeNode {public char val;public TreeNode left;public TreeNode right;public TreeNode(char val) {this.val = val;}}public class Main {public static int i = 0;public static TreeNode creatTree(String str) {TreeNode root = null;if (str.charAt(i) != '#') {root = new TreeNode(str.charAt(i));i++;root.left = creatTree(str);root.right = creatTree(str);} else {i++;}return root;}public static void inOrder(TreeNode root) {if (root == null) {return;}inOrder(root.left);System.out.print(root.val + " ");inOrder(root.right);}public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseString str = in.nextLine();TreeNode root = creatTree(str);inOrder(root);}}}
第十题
二叉树的分层遍历 。OJ链接
利用队列在装这些元素,如果root=null直接返回。不为空,则入队一个root,队列不为空的话把这个打印出来,出队,如果这个root左右子树不为空,入队,然后进行循环,直到一整颗树被打印完。为什么用队列而不用栈呢?如果用栈就从 右往左打印了,显然不符合层序遍历的规律。
public void levelOrder(TreeNode root){Queue<TreeNode> queue=new LinkedList<>();if(root==null){return;}queue.offer(root);while(!queue.isEmpty()){TreeNode cur=queue.poll();System.out.print(cur.val+" ");if(cur.left!=null){queue.offer(cur.left);}if(cur.right!=null){queue.offer(cur.right);}}System.out.println();}
第十一题
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先 。OJ链接
也是利用结构判断,如果root=null,返回null;如果p和q任意有个人在root,直接返回root;如果没有,继续递归,看看左右子树:如果左右子树都找得到p或q,那么说明左右子树各有一个,它的祖先必然是root;如果都在左子树,找到一个就返回,都在右子树,找到一个就返回。
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root==null){return null;}if(root==p||root==q){return root;}TreeNode leftTree=lowestCommonAncestor(root.left,p,q);TreeNode rightTree=lowestCommonAncestor(root.right,p,q);//左子树和右子树各一个if(leftTree!=null&&rightTree!=null){return root;}//都在左子树,找到一个就返回else if(leftTree!=null){return leftTree;}//都在右子树,找到一个就返回else{return rightTree;}}
相关文章:
“手撕”二叉树的OJ习题
故事的开头,我们先来三道不是oj的开胃菜,练练手感,后面9道都是OJ题。 目录 第一题 第二题 第三题 第四题 第五题 第六题 第七题 第八题 第九题 第十题 第十一题 第一题 二叉树前序非递归遍历实现 。 首先我们需要一个栈来存放二…...
Linux Mint 21.3简介
Linux Mint 21.3是一个更新版本,其中包含了许多新特性和改进。以下是一些主要更新内容: 1. Cinnamon 6.0桌面环境:Linux Mint 21.3采用了最新的Cinnamon 6.0桌面环境,带来了新的功能和改进,例如支持Wayland会话&#…...
C++11 面试题整理
C面试题 1 菱形继承 2 多态 多态实现原理: 静态多态 动态多态 静态多态: 依赖函数重载,编译期确定。 函数重载:允许在同一作用于内声明多个功能类似的同名函数,函数列表不同。注意:不能仅通过返回值类型…...
【智能制造-2】焊缝跟踪
焊缝跟踪? 焊缝跟踪:指在焊接位置前方安装光学传感器进行数据采集,然后传输到焊接机器人,进行自适应的各种模糊控制算法校正焊接机器人或专机的轨迹,实现自适应控制,达到实时的焊缝跟踪。 焊缝跟踪的方法…...
优思学院|用ChatGPT快速完成数据分析图表【柏累托图法】
数据分析是很多行业的人不可少的一部分,尤其是质量工程师更是日常的工作。然而,随着科技的进步,人工智能(AI)将逐渐承担起数据计算的工作,这意味着未来的质量工程师需要具备的不仅仅是计算能力,…...
[晕事]今天做了件晕事37 extern “C“ 被认为了是外部函数
最近看到一个函数声明是 extern “C" void _dump(); 这里的声明是要告诉编译器,这个_dump是C语言的符号,没有经过mangle过的。但是这个关键字可能让人混淆是外部函数。因为这个关键字可以声明外部函数。这也算是一词多用的一个普遍问题。关键的关键…...
问题:关于醋酸钠的结构,下列说法错误的是() #媒体#媒体
问题:关于醋酸钠的结构,下列说法错误的是() A.有极性键 B.有非极性键 C.是极性分子 D.是离子晶体 参考答案如图所示...
网络安全(补充)
同步包风暴(SYN Flood)攻击者假造源网址发送多个同步数据包(SYN Packet)给服务器,服务器因无法收到确认数据包(ACK Packet),使TCP/IP协议三次握手无法顺利完成,因而无法建…...
Redis集群(3)
集群扩容 节点配置和启动 我们要加入两个节点,主节点端口为6903,从节点端口为6933。配置与6900节点类似,不再赘述。启动这两个节点: ./redis-server ../conf/cluster_m_6903.conf ./redis-server ../conf/cluster_s_6933.conf加…...
防止Selenium被检测 Google Chrome 125
背景 最近在使用selenium自动播放学习课程,相信大家也有一些类似的使用场景。 能自动化的事情,绝不自己干。 为防止被检测是机器人做题,刷视频,需要做一些小调整。 先来看作为服务方维护者,是如何检测是Selenium打…...
LeetCode 算法:螺旋矩阵c++
原题链接🔗:螺旋矩阵 难度:中等⭐️⭐️ 题目 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&…...
【全开源】医护上门系统小程序APP公众号h5源码
医护上门系统:健康守护,就在您身边 🚪引言:开启全新的医护模式 在快节奏的现代生活中,健康问题往往成为我们关注的焦点。而“医护上门系统”正是为了满足这一需求,将专业的医疗服务送到您的家中。这一创新…...
结构体<C语言>
导言 结构体是C语言中的一种自定义类型,它的值(成员变量)可以是多个,且这些值可以为不同类型,这也是和数组的主要区别,下面将介绍它的一些基本用法,包括:结构体的创建、结构体变量的…...
点云分割报告整理(未完成版-每天写一点)
体积占用网格表示对点进行体素化,然后使用3d卷积神经网络来学习体素级语义。由于点云的稀疏性,体素化效率低,为避免较高的计算成本而忽略了细节。此外,由于同一体素内的所有点都被赋予了相同的语义标签,因此精度受到限…...
python基础 002 - 1 基础语法
1 标识符(identifier),识别码,表明身份 身份证,ID 定义:在编程语言中标识符就是程序员自己规定的具有特定含义的词,比如类名称、属性名称、变量名等, 在Python 中,pyt…...
浅谈Web开发的三大主流框架:Angular、React和Vue.js
在现代Web开发领域,Angular、React和Vue.js作为三大主流前端框架,各自拥有独特的特点和优势,为开发者提供丰富的选择。让我们更深入地了解这三大框架,并通过一些小型样例来展示它们的特性。 Angular Angular是一个完整的前端框架…...
使用net.sf.mpxj读取project的.mpp文件
1、导入.mpp文件 public void importMppFile(String updateType, MultipartFile multipartFile) {try (InputStream inputStream multipartFile.getInputStream()) {// 读取文件的组件MPPReader mppReader new MPPReader();// 注意,如果在这一步出现了读取异常&a…...
ubuntu 22.04 升级到24.04
step1. sudo apt update sudo apt upgrade sudo apt dist-upgrade step2. sudo apt autoremove step3. sudo apt install update-manager-core step4. sudo vim /etc/update-manager/release-upgrades 将 Prompt 设置为 lts: Promptlts 保存并退出 step5. sudo do-r…...
FreeRTOS学习笔记-基于stm32(14)内存管理
一、FreeRTOS 内存管理简介 FreeRTOS有两种方法来创建任务,队列,信号量等,一种动态一种静态。静态方法需要手动定义任务堆栈。使用动态内存管理的时候 FreeRTOS 内核在创建任务、队列、信号量的时候会动态的申请 RAM。 我们在移植FreeRTOS时可…...
关于Lambert W函数
来源:R. M. Corless, G. H. Gonnet, D. E. G. Hare, D. J. Jeffrey, and D. E. Knuth, “On Lambert’s W function,” Adv. Comput. Math., vol. 5, pp. 329–359, May 1996, doi: 10.1007/BF02124750. 摘要 Lambert W函数被定义为函数 w ↦ w e w w \mapsto we^…...
【免杀】C2远控-APC注入-进程镂空
目录 进程镂空&傀儡进程(主要过内存扫描)代码 傀儡进程演示如何上线上线演示 APC注入&进程欺骗(主要过内存扫描)同步调用与异步调用代码演示 进程镂空&傀儡进程(主要过内存扫描) 进程镂空(Pro…...
20240611 讯飞JAVA工程师(研发经理岗)面试
1.线程安全的集合类 在Java中,一些线程安全的集合类有Stack、Vector、Properties、Hashtable等 2.线程池中execute和submit的区别 1)参数及返回值不同 excute只能提交Runnable,无返回值 submit既可以提交Runnable,返回值为null&am…...
【研发日记】Matlab/Simulink软件优化(三)——利用NaNFlag为数据处理算法降阶
文章目录 前言 背景介绍 初始算法 优化算法 分析和应用 总结 前言 见《【研发日记】Matlab/Simulink软件优化(一)——动态内存负荷压缩》 见《【研发日记】Matlab/Simulink软件优化(二)——通信负载柔性均衡算法》 背景介绍 在一个嵌入式软件开发项目中,需要开…...
go语言接口之http.Handler接口
package httptype Handler interface {ServeHTTP(w ResponseWriter, r *Request) }func ListenAndServe(address string, h Handler) error ListenAndServe函数需要一个例如“localhost:8000”的服务器地址,和一个所有请求都可以分 派的Handler接口实例。它会一直运…...
R语言 | 使用最简单方法添加显著性ggpubr包
本期教程原文:使用最简单方法添加显著性ggsignif包 本期教程 获得本期教程代码和数据,在后台回复关键词:20240605 小杜的生信笔记,自2021年11月开始做的知识分享,主要内容是R语言绘图教程、转录组上游分析、转录组下游…...
【Linux】shell脚本变量——系统变量、环境变量和用户自定义变量
系统变量 系统变量是由系统预设的,它们通常在系统启动时被加载,并对所有用户和所有shell实例都有效。这些变量通常控制着系统的行为和配置,例如PATH(命令搜索路径)、HOME(用户主目录)等。系统变…...
QWidget 属性——windowTitle·windowIcon·qrc
🐌博主主页:🐌倔强的大蜗牛🐌 📚专栏分类:QT ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 一、windowTitle二、windowIcon三、qrc 一、windowTitle windowTitle 是一个通常用于表示窗口标题…...
深入理解rtmp(一)之开发环境搭建
深入理解rtmp(一)之开发环境搭建 手机直播在15年的时候突然火起来,随着花椒,映客等出现,直播一下就出现在了风口,各个公司针对直播的战斗迅速打响,战斗过程比较短暂,随着许多公司的退出和死去,手机直播行业趋于稳定,直播服务时长也被传统的CDN厂商牢牢占据,后面大家又把精力投…...
java常用面试基础题
&与&&区别? &和&&都是逻辑运算符,都是判断两边同时真则为真,否则为假;但是&&当第一个条件不成之后,后面的条件都不执行了,而&则还是继续执行,直到整个条件…...
互联网摸鱼日报(2024-06-11)
互联网摸鱼日报(2024-06-11) 36氪新闻 雅诗兰黛,胆子也太大了 苹果WWDC终极前瞻:5大看点20大AI新功能,库克不能输的一战 瑞士清洁科技公司Enerdrape开发预制地热板,回收城市地下空间的浅层地热能和废热用于建筑物制热或制冷 | …...
武汉网站制作好/数据网站
之前我们做的都是单表查询,那么问题来了,如果我们想要做多表关联查询该怎么处理呢,本篇Blog来探索关联查询(多对一关系)和集合查询(一对多关系)的实现方式。同样还是在之前的Person表基础上做一…...
鹤壁哪里做网站/电商是做什么的
毕业之前一直在做前端开发,毕业后就转成做iOS开发,这两者有很多挺有意思的对比,尝试写下我能想到的它们的一些相同点和不同点。 语言 前端和终端作为面向用户端的程序,有个共同特点:需要依赖用户机器的运行环境&#x…...
白云区网站开发公司电话/品牌推广方式
平衡电桥 等电位点之间连接任意的阻值不会破坏其他支路量 因为电流计两端电势相等,电压为0,所以没有电流 等效电路...
岳阳整站优化/关键词搜索推广
UINavigationController详解 通过这个接口可以初始化自定义的工具栏和导航栏 - (instancetype)initWithNavigationBarClass:(Class)navigationBarClass toolbarClass:(Class)toolbarClass NS_AVAILABLE_IOS(5_0) 使用水平滑动过渡。如果视图控制器已在堆栈中在调用就没有效果 -…...
郑州网站建设网站推广/哪个网站做推广效果好
android:resizeableActivity[“true” | “false”] 如果该属性设置为 true,Activity 将能以分屏和自由形状模式启动。 如果此属性设置为 false,Activity 将不支持多窗口模式。 如果该值为 false,且用户尝试在多窗口模式下启动 Activity&…...
做品牌文化的网站/南宁seo优化公司排名
https://www.luogu.org/problem/show?pid1197 感觉并查集要维护删除好像很棘手; 开两个并查集也无法解决问题; 尴尬; 本着zyy大神的不是考试懒得想的理念发了一下题解; 发现只要倒着来就好了; 就是离线做&#…...