【数据结构】二叉树(三)精选Oj题

本篇已经是二叉树第三篇啦,下面讲解相关面试题,写作不易,求路过的朋友给个点赞与收藏呀~

目录

1、相同的树

2、另一颗树的子树 

 3、翻转二叉树

 4、对称二叉树

5、平衡二叉树

 6、构建二叉树

7、二叉树的最近公共祖先

孩子双亲解法

二叉搜索树解法 

普通二叉树解法    

8、二叉树创建字符串


判断两棵树是否相同、另一颗的子树、反转二叉树、判断是否为平衡二叉树、对称二叉树、二叉树的构建、最近公共祖先结点、根据前序与中序遍历构造二叉树、根据后序与中序遍历构造二叉树、二叉树创建字符串

1、相同的树

解题思路:

同时遍历两棵树

  1. 如果两棵树都是空,则相同
  2. 如果两棵树一个为空,一个不为空,则不相同
  3.  如果两棵树都不为空,先检测值是否相同,根如果相同再递归检测两棵树的左子树以及右子树是否都相同
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.val != q.val)return false;return isSameTree(p.left, q.left) &&isSameTree(p.right, q.right);}
}

2、另一颗树的子树 

解题思路:

  1. 空树是任意一棵树的子树
  2. 如果两棵树相同,也可以认为是子树,因此:只要根节点相同,直接检测s和t是否为相同的树即可
  3. 如果根不相同,检测t是否为s.left的子树 或者 s.right的子树 

class Solution {//判断subRoot是否为root子树public boolean isSubtree(TreeNode root, TreeNode subRoot) {if (root == null) {return false;}
//subRoot可能与root相同,可能与root.left 、root.right相同
//其中一种情况为true,则为子树return isSameTree(root, subRoot) || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);}//判断参数中两树是否相同public boolean isSameTree(TreeNode p, TreeNode q) {if (p == null && q == null) {return true;} else if (p == null || q == null) {return false;} else if (p.val != q.val) {return false;} else {return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);}}
}

【易错点】

        return isSameTree(root, subRoot) || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot);

(root.left, subRoot)与(root.right, subRoot)参数应传入Subtree方法中进行递归,若传入isSameTree方法中只能判断一次root的左右子树与subRoot是否相同


 3、翻转二叉树

解题思路:

二叉树前序遍历规则应用, 如果树不空时:

  1. 交换根的左右子树
  2. 递归反转根的左子树
  3. 递归反转根的右子树 
class Solution {public TreeNode invertTree(TreeNode root) {if(root==null)return null;//借助ret将root.left、root.right交换TreeNode ret=null;ret=root.left;root.left=root.right;root.right=ret;//递归反转根的左子树invertTree(root.left);
//递归反转根的右子树 invertTree(root.right);return root;}
}

 4、对称二叉树

 

解题思路:

直接递归检测root的左右是否对称即可

  1. 如果两棵树都是空树,则对称
  2. 如果两棵树一棵为空树,一棵不为空树,则一定不是对称树
  3. 如果两棵树都不为空,先检测两棵树的root是否相同,如果相同,再检测一个的left是否为另一个的right 并且一个的right是否为另一个的left
class Solution {public boolean isSymmetric(TreeNode root) {return isSym(root.left, root.right);}//判断对称public boolean isSym(TreeNode p, TreeNode q) {if(p==null&&q==null)return true;if(p!=null&&q==null||p==null&&q!=null)return false;if(p.val!=q.val)return false;return isSym(p.left,q.right)&&isSym(p.right,q.left); }
}

5、平衡二叉树

平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1。

解题思路:

平衡二叉树的概念:二叉树中每个节点左右子树高度差的绝对值不能超过1 根据概念来检测:

  1. 如果是空树,直接返回,注意:空树也是平衡二叉树
  2. 求根的左右子树高度,然后做差检测其高度差的绝对值是否超过1 如果超过则不是
  3. 递归检测根的左右子树是否为平衡二叉树
class Solution {
//计算root的深度public int GetHeight(TreeNode root){if(root == null){return 0;}int leftHeight = GetHeight(root.left);int rightHeight = GetHeight(root.right);
//三目运算符,root深度为左右子树更大值加1return leftHeight > rightHeight? leftHeight+1 : rightHeight+1;}//判断是否平衡public boolean isBalanced(TreeNode root) {// 空树是平衡二叉树if(root == null){return true;}// 获取root左右子树的高度int leftHeight = GetHeight(root.left);int rightHeight = GetHeight(root.right);// 根据平衡树的概念,检测root节点的平衡性if(Math.abs(rightHeight - leftHeight) >= 2){return false;}// 通过递归方式:检测root的左右子树是否为平衡树return isBalanced(root.left) && isBalanced(root.right);}
}

 6、构建二叉树

这道题偏难,可以点进牛客网链接测试,链接放这里啦

根据字符串构建二叉树

//结点类
class TreeNode {char val;TreeNode left;TreeNode right;public TreeNode(char val) {this.val = val;}
}
public class Main {static int i = 0;//创建二叉树public static TreeNode setUp(String str) {TreeNode node = null;//依次取出str字符串的每个字符char ch = str.charAt(i);if (ch != '#') {node = new TreeNode(ch);i++;node.left = setUp(str);node.right = setUp(str);} else {i++;}return node;}//中序遍历public static void inOrderTraversal(TreeNode root) {if (root == null)return;inOrderTraversal(root.left);System.out.print(root.val + " ");inOrderTraversal(root.right);}
//main方法public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNext()) { // 注意 while 处理多个 caseString str = in.nextLine();TreeNode root = setUp(str);inOrderTraversal(root);}}
}

 注意事项

OJ算法题分为两种类型:

  1. 接口类型OJ:此种OJ题目是方法名字已经给好,用户直接写代码即可,也不需要包含什么包
  2. IO类型的OJ:此种OJ题目需要用户定义一个public的Main类,然后在Main类中提供一个main方法,在main方法中完成事情,中间如要需要用到其他集合类,必须手动 导入包 在线OJ中的循环输入,输入单个值怎么循环接收,整行值怎么循环接收

7、二叉树的最近公共祖先

这道题有多种解法 对二叉树分情况:

孩子双亲解法

如果二叉树采用孩子双亲表示法链接,求两个节点的最近公共祖先,实际就转化为两个链表相交求交点  

二叉搜索树解法 

a. 如果树是空,直接返回null,没有最近公共祖先节点

b. 如果两个节点中有一个是根节点,最近公共祖先一定是根节点

c. 如果两个节点一个比根节点大,一个比根节点小,最近公共祖先一定是根节点

d. 如果两个节点都比根节点小,递归到根的左子树中查找

e. 如果两个节点都比根节点大,递归到根的右子树中查找        

普通二叉树解法    

 方法一:

写一个判断节点是否在二叉树中的方法,可以参考类似二叉搜索树的方法解觉

  • 如果树是空,直接返回null,没有最近公共祖先节点
  • 如果两个节点中有一个是根节点,最近公共祖先一定是根节点
  • 如果两个节点一个在根节点的左子树,一个在根节点的右子树,最近公共祖先一定是根节点
  • 如果两个节点都在左子树中,递归到左子树中找
  • 如果两个节点都在右子树中,递归到右子树中找    

方法二:受孩子双亲表示法启发,如果能够知道节点到根的路径,问题就解决了

获取节点pNode的路径,因为公共祖先从下往上找,因此将路径中的节点保存在栈中

  • 如果是空树,直接返回 
  • 将根节点入栈,如果根节点和pNode是同一个节点,该节点到根的路径找到,否则:
  • 递归在根节点的左子树中查找,如果找到,返回
  • 如果在根节点的左子树中未找到,递归到根节点的右子树中找
  • 如果右子树中没有找到,说明root一定不再路径中                 

方法三:将两个节点的路径存入栈中

  1.   在二叉树中获取两个节点的路径
  2. 如果两个路径中节点个数不一样,节点多的出栈,直到两个栈中元素相等
  • 相等时:再比较两个栈顶是不是同一个节点,
  • 如果是,最近公共祖先找到。
  • 如果不是,两个栈同时进行出栈,继续比较,直到找到为止   

下面以 普通二叉树解法 方法一举例,代码有注释哈

class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if (root == null)return null;if (root == p)return p;if (root == q)return q;// 找出root的左子树是否有p/q结点TreeNode leftTree = lowestCommonAncestor(root.left, p, q);// 找出root的右子树是否有p/q结点TreeNode rightTree = lowestCommonAncestor(root.right, p, q);// 若左右子树都不为空,说明找到了p、q,则最近祖先为rootif (rightTree != null && leftTree != null)return root;// 若左子树不为空右子树为空,最近祖先为root.leftif (leftTree != null)return leftTree;// 若左子树为空右子树不为空,最近祖先为root.rightreturn rightTree;}
}

8、二叉树创建字符串

 解题思路: 采用二叉树前序遍历规则进行转化

  1. 如果树空,转化结束
  2. 如果树非空
  • 先转化跟节点
  • 转化根节点的左子树, 如果根的左子树非空或者左子树空但是右子树非空:( 递归转化左子树 ), 注意将转化结果内嵌到()中
  • 转化根节点的右子树 ,如果根的右子树非空:( 递归转化右子树 ), 注意将转化结果内嵌到()中
class Solution {
String str;public String tree2str(TreeNode t) {StringBuilder sb = new StringBuilder();tree2str(t, sb);return sb.toString();}public void tree2str(TreeNode t, StringBuilder str) {if(null == t){return;}// 先将根节点的数据放到str中str.append(t.val);// 处理根节点的左子树if(null != t.left || null != t.right){// 左子树非空,递归转化左子树str.append("(");tree2str(t.left, str);str.append(")");}// 再检测t的右子树,如果右子树为空,不增加任何内容if(null != t.right){// 递归处理右子树str.append("(");tree2str(t.right, str);str.append(")");}}
}

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

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

相关文章

大端存储与小端存储

大端存储与小端存储 什么大端存储什么是小端存储 大端存储(Big-endian)和小端存储(Little-endian)是计算机科学中数据在内存中存储的两种不同方式,主要涉及多字节数据类型(如整数、浮点数)的字…

vue3 组合式 API:setup()

查看vue3官网介绍:组合式 API:setup() 在 Vue 3 中,组合式 API 的 setup() 函数是一个非常重要的特性,它提供了一种更灵活和可维护的方式来组织组件的逻辑。 基本概念 setup() 函数是在组件实例创建之前执行的,它用于…

零基础STM32单片机编程入门(三十八) 多传感器模块之跌倒检测实战源码

文章目录 一.概要二.实验原理三.实验控制流程四.STM32单片机跌倒监测实验(MPU6050直流有刷电机蜂鸣器)五.CubeMX工程源代码下载六.实验效果视频七.小结 一.概要 据统计每年约有 300 万老年人因跌倒受伤而在急诊室接受治疗,每五次跌倒就有一次会造成伤害&#xff0c…

网络如何发送一个数据包

网络如何发送一个数据包 网络消息发送就是点一点屏幕。 骚瑞,这一点都不好笑。(小品就是我的本质惹) 之前我就是会被这个问题搞的不安宁。是怎么知道对方的IP地址的呢?怎么知道对方的MAC呢?世界上计算机有那么多&…

阿里Qwen2开源大模型本地部署及调试全攻略

阿里Qwen2开源大模型本地部署及调试全攻略 #Qwen2系列大模型性能卓越,超越业界知名模型。开源后受到AI开发者关注,支持多种语言,提升多语言理解。在预训练和微调上优化,实现智能水平提升。Qwen2系列模型在各项能力上均领先&#…

python 获取pdf文件中的超链接

pip install pymupdf pip install fitzimport fitz # PyMuPDFdef get_pdf_links(pdf_path):# 打开PDF文件document fitz.open(pdf_path)links []for page_num in range(len(document)):page document[page_num]# 获取当前页面的链接for link in page.get_links():links.app…

WPF自定义控件

控件模板 顾名思义就是在原有的控件上进行模版修改成自己需要的样式 把ProgressBar修改为一个水液面的进度条 <Window x:Class"XH.CustomLesson.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://s…

2024年第三届全国大学生数据分析实践赛A 题

↑ ↑ ↑ ↑ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑ ↑ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ ↑​​​​​​​ …

【Java学习】方法的引用

所属专栏&#xff1a;Java学习 &#x1f341;1. 方法引用 方法的引用&#xff1a;把已经存在的方法拿来使用&#xff0c;当作函数式接口中抽象方法的方法体 " :: "是方法引用符 方法引用时需要注意&#xff1a; 1. 需要有函数式接口 2. 被引用的方法必须存在 3. …

浅谈SIMD、向量化处理及其在StarRocks中的应用

前言 单指令流多数据流(SIMD)及其衍生出来的向量化处理技术已经有了相当的历史&#xff0c;并且也是高性能数据库、计算引擎、多媒体库等组件的标配利器。笔者在两年多前曾经做过一次有关该主题的内部Geek分享&#xff0c;但可能是由于这个topic离实际研发场景比较远&#xff0…

3:html(CSS):基础语法3

3.1网页布局与id 3.1.1网页布局 在这里将使用<div>分成一个一个的块&#xff0c;然后进行CSS的美化。这里要说一下html是一个前端的代码&#xff0c;但是它写出来的东西单调缺少美感&#xff0c;CSS就是进行美化的&#xff0c;这里我们使用类的概念来美化我们的网站。 …

X-Recon:一款针对Web安全的XSS安全扫描检测工具

关于X-Recon X-Recon是一款功能强大的Web安全扫描与检测工具&#xff0c;该工具能够帮助广大研究人员识别网页端输入数据&#xff0c;并执行XSS扫描任务。 功能介绍 1、子域名发现&#xff1a;检索目标网站的相关子域名并将其整合到白名单中。这些子域名可在抓取过程中使用&am…

Vue+ElementUI技巧分享:创建一个带有进度显示的文件下载和打包组件

在现代前端开发中&#xff0c;用户体验至关重要&#xff0c;尤其是在处理文件下载时。为用户提供实时的下载进度显示和打包功能&#xff0c;不仅能提升用户体验&#xff0c;还能使应用更具专业性。在本文中&#xff0c;我们将创建一个 Vue 组件&#xff0c;用于显示文件下载进度…

与人打交道的七个绝招

与人打交道的七个绝招&#xff0c;学会了让你混得风生水起&#xff01; 一、跟强者打交道&#xff0c;别绕圈子。就事论事&#xff0c;直奔主题&#xff1b; 二、跟没钱的人打交道&#xff0c;就直接告诉他能挣多少钱&#xff1b; 三、跟小人打交道&#xff0c;越虚假越好&…

URP平面阴影合批处理 shadow

闲谈 相信大家在日常工作中发现了一个问题 &#xff0c; urp下虽然可以做到3个Pass 去写我们想要的效果&#xff0c;但是&#xff0c;不能合批&#xff08;不能合批&#xff0c;那不是我们CPU要干冒烟~&#xff01;&#xff09; 好家伙&#xff0c;熊猫老师的偏方来了 &#x…

JavaScript基础(33)_鼠标滚轮滚动事件、键盘事件

鼠标滚轮滚动事件&#xff1a;onwheel 获取鼠标滚轮滚动的方向&#xff1a;wheelDelta 比如&#xff1a;向上滚动&#xff1a;109 &#xff08;所有正值都是向上&#xff09; 向下滚动&#xff1a;-109&#xff08;所有负值都是向下&#xff09; 注意&#xff1a;当…

基于华为atlas下的yolov5+BoT-SORT/ByteTrack煤矿箕斗状态识别大探索

写在前面&#xff1a; 本项目的代码原型基于yolov5yolov8。其中检测模型使用的yolov5&#xff0c;跟踪模型使用的yolov8。 这里说明以下&#xff0c;为什么不整体都选择yolov8呢&#xff0c;v8无疑是比v5优秀的&#xff0c;但是atlas这块经过不断尝试没有过去&#xff0c;所以…

AWS boto3 脚本访问 AWS 资源

AWS boto3 脚本访问 AWS 资源 引言boto3主要功能常见用例安装和基本使用 boto3.Client() 低级客户端基本用法关键参数 boto3.resource() 高级客户端常见参数用法 boto3.resource VS boto3.client相似点不同点总结 关于身份验证凭证隐式身份凭证显式身份验证凭证assuem role如何…

出海笔记精华问答 | 第四期

更新出海问答第四期&#xff0c;希望可以继续帮助大家解决问题哈。 Q1:当stripe把资金全退给客户但是货又发了&#xff0c;这是什么情况&#xff1f; A1: 这种情况一般是stripe不跟你合作了或者发生了争议。 Q2:如何知道stripe回复你的邮件是人工回复还是机器人回复&#xff…

Linux基础入门---安装vmware

&#x1f600;前言 本篇博文是关于Linux基础入门和vmwarel5.5下载&#xff0c;希望你能够喜欢。 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动…