二叉树习题-小记

news2025/1/6 16:06:19

文章目录

    • 二叉树
      • 相同的树
      • 572. 另一棵树的子树
      • 110. 平衡二叉树
      • 101. 对称二叉树
      • 236. 二叉树的最近公共祖先
      • JZ36 二叉搜索树与双向链表
      • 105. 从前序与中序遍历序列构造二叉树
      • 606 根据二叉树创建字符串

二叉树

相同的树

相同的树
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。

示例 1:
在这里插入图片描述

输入:p = [1,2,3], q = [1,2,3]
输出:true

示例 2:
在这里插入图片描述

输入:p = [1,2], q = [1,null,2]
输出:false

思路:

  1. 判断根节点(结构和值)
  2. 递归结点p的左树和结点q的左树;
    递归结点p的右树和结点q的右树
/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p!=null&&q==null||p==null&&q!=null){
            return false;
        }
        if(p==null&&q==null){
            return true;
        }
        //p\q都不为null
        if(p.val!=q.val){
            return false;
        }
        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
        
    }
}

572. 另一棵树的子树

另一棵树的子树
给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在,返回 true ;否则,返回 false 。

二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree 也可以看做它自身的一棵子树。

示例 1:
在这里插入图片描述

输入:root = [3,4,5,1,2], subRoot = [4,1,2]
输出:true

示例 2:
在这里插入图片描述

输入:root = [3,4,5,1,2,null,null,null,null,0], subRoot = [4,1,2]
输出:false

思路:

  1. 判断 subRoot是不是和root相同
  2. subRoot是不是root的左子树
  3. subRoot是不是root的右子树
/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        if(root==null||subRoot==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;
    }
    public boolean isSameTree(TreeNode p, TreeNode q) {
        if(p!=null&&q==null||p==null&&q!=null){
            return false;
        }
        if(p==null&&q==null){
            return true;
        }
        //p\q都不为null
        if(p.val!=q.val){
            return false;
        }
        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);    
    }
}

110. 平衡二叉树

平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。

示例 1:
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:true

示例 2:
在这里插入图片描述

输入:root = [1,2,2,3,3,null,null,4,4]
输出:false

示例 3:

输入:root = []
输出:true

思路:
平衡:每棵子树左右高度差不能超过1

  • root平衡
  • root.left平衡
  • root.right 平衡
    在计算高度时,判断当前的结点是否平衡,若不平衡,向上返回-1.
/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
        return maxDepth(root)>=0;
    }
    public int maxDepth(TreeNode root){
        if(root==null){
            return 0;
        }
        int leftH=maxDepth(root.left);
        int leftR=maxDepth(root.right);

        //一个结点左右子树遍历完
        if(leftH>=0&&leftR>=0&&Math.abs(leftH-leftR)<=1){
            return Math.max(leftH,leftR)+1;
        }else{
            return -1;//说明不平衡
        }
    }
}

101. 对称二叉树

对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

示例 1:
在这里插入图片描述

输入:root = [1,2,2,3,4,4,3]
输出:true

示例 2:
在这里插入图片描述

输入:root = [1,2,2,null,3,null,3]
输出:false

思路:

  1. 判断左树右树是不是对称的
  2. 判断时存在以下情况
  • 1.一个为空,一个不为空
  • 2.两个都为空
  • 3.值是不是一样的
/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root==null){
            return true;
        }
        //判断左树右树是不是对称的
        return isSymmetricChild(root.left,root.right);

    }
    public boolean isSymmetricChild(TreeNode leftTree,TreeNode rightTree){
        //1.一个为空,一个不为空
        if(leftTree==null&&rightTree!=null||leftTree!=null&&rightTree==null){
            return false;
        }
        //2.两个都为空
        if(leftTree==null&&rightTree==null){
            return true;
        }
        //3.值是不是一样的
        if(leftTree.val==rightTree.val){
            return isSymmetricChild(leftTree.left,rightTree.right)&&isSymmetricChild(leftTree.right,rightTree.left);
        }
        return false;
    }
}

236. 二叉树的最近公共祖先

二叉树的最近公共祖先

思路:

  1. 若p、q在root的左右两边,则root为最近公共祖先。
  2. 若p、q同在左子树,或同在右子树中,则搜索到的返回的第一个结点即为最近公共祖先。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    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;
        }
        if(leftTree!=null&&rightTree==null){
            return leftTree;
        }
        if(leftTree==null&&rightTree!=null){
            return rightTree;
        }
        return null;
    }
}

1.还可以使用 两个链表求交点(p到公共祖先、q到公共祖先看作两个链表),但前提是每个节点需包含parent域。
2.利用栈,从root节点到p的所有节点插入栈1中,从root节点到q的所有节点放入栈2中,根据栈1和栈2中size的差值,将栈元素数量多的栈元素弹出,直到两个栈中元素数量一致;然后栈1和栈2同时弹出元素,直到弹出的元素相等,即为 【最近公共祖先】

JZ36 二叉搜索树与双向链表

JZ36 二叉搜索树与双向链表

描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示
在这里插入图片描述
数据范围:输入二叉树的节点数 0≤n≤1000,二叉树中每个节点的值 0≤val≤1000
要求:空间复杂度O(1)(即在原树上操作),时间复杂度 O(n)

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public TreeNode prev=null;
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
            return null;
        }
        ConvertChild(pRootOfTree);

        TreeNode head=pRootOfTree;
        while(head.left!=null){
            head=head.left;
        }
        return head;
    }
    public void ConvertChild(TreeNode pCur){
        if(pCur==null){
            return ;
        }
        ConvertChild(pCur.left);
        pCur.left=prev;
        if(prev!=null){
            prev.right=pCur;
        }
        prev=pCur;
        ConvertChild(pCur.right);
    }
}

105. 从前序与中序遍历序列构造二叉树

从前序与中序遍历序列构造二叉树
关键在于通过preorder得知根结点,在inorder 中找到根节点下标,以此划分左右子树,再根据左右子树下标区间进行递归,来构造二叉树。

/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public int preIndex=0;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return buildTreeChild(preorder,inorder,0,inorder.length-1);
    }
    public TreeNode buildTreeChild(int[] preorder,int[] inorder,int inbegin,int inend){
        if(inbegin>inend){
            return null;//说明没有左树 或者 没有右树
        }
        TreeNode root=new TreeNode(preorder[preIndex]);

        int rootIndex=findIndex(inorder,preorder[preIndex],inbegin,inend);
        preIndex++;
        root.left=buildTreeChild(preorder,inorder,inbegin,rootIndex-1);
        root.right=buildTreeChild(preorder,inorder,rootIndex+1,inend);
        return root;
    }
    public int findIndex(int[] inorder,int key,int inbegin,int inend){
        for(int i=inbegin;i<=inend;i++){
            if(inorder[i]==key){
                return i;
            }
        }
        return -1;
    }
}

同理106. 从中序与后序遍历序列构造二叉树
从中序与后序遍历序列构造二叉树

/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public int postIndex=0;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        postIndex=postorder.length-1;
        return buildTreeChild(inorder,0,inorder.length-1,postorder);
    }
    public TreeNode buildTreeChild(int[] inorder,int inbegin,int inend,int[] postorder){
        if(inbegin>inend){
            return null;
        }
        TreeNode root=new TreeNode(postorder[postIndex]);

        int rootIndex=findIndex(inorder,inbegin,inend,postorder[postIndex]);
        postIndex--;
        root.right=buildTreeChild(inorder,rootIndex+1,inend,postorder);
        root.left=buildTreeChild(inorder,inbegin,rootIndex-1,postorder);
        return root;
    }
    public int findIndex(int[] inorder,int inbegin,int inend,int key){
        for(int i=inbegin;i<=inend;i++){
            if(inorder[i]==key){
                return i;
            }
        }
        return -1;
    }
}

606 根据二叉树创建字符串

根据二叉树创建字符串

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。

空节点使用一对空括号对 “()” 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

示例 1:
在这里插入图片描述

输入:root = [1,2,3,4]
输出:“1(2(4))(3)”
解释:初步转化后得到 “1(2(4)())(3()())” ,但省略所有不必要的空括号对后,字符串应该是"1(2(4))(3)" 。

示例 2:
在这里插入图片描述

输入:root = [1,2,3,null,4]
输出:“1(2()(4))(3)”
解释:和第一个示例类似,但是无法省略第一个空括号对,否则会破坏输入与输出一一映射的关系。

/**
 * Definition for a binary tree node.
 * 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;
 *     }
 * }
 */
class Solution {
    public String tree2str(TreeNode root) {
        StringBuilder sb=new StringBuilder();
        if(root==null){
            return sb.toString();
        }
        tree2strChild(root,sb);
        return new String(sb);
    }
    public void tree2strChild(TreeNode t,StringBuilder sb){
        if(t==null){
            return ;
        }
        sb.append(t.val);//根  左  右
        if(t.left!=null){
            sb.append("(");
            tree2strChild(t.left,sb);
            sb.append(")");
        }else{
            if(t.right==null){
                return;
            }else{
                sb.append("()");
            }
        }
        if(t.right==null){
            return;
        }else{
            sb.append("(");
            tree2strChild(t.right,sb);
            sb.append(")");
        }
    }
}

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

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

相关文章

秒杀同龄人的顶级复盘能力,坚持1年,领先5年!

什么是复盘 复盘一词起源于围棋术语&#xff0c;本意是对弈者下完一盘棋之后&#xff0c;重新把过程摆一遍&#xff0c;看哪些地方下得好&#xff0c;哪些不好&#xff0c;总结经验。 在头脑中把过去做的事情“过”一遍&#xff0c;通过对过去的思维和行为进行回顾、反思和探…

使用STM32CubeMX实现LED闪烁

需提前学习&#xff1a;STM32CubeMX新建工程并点亮一个LED&#xff1b; 目录 打开GPIO相关文件 我们需要看的部分 HAL_GPIO_ReadPin&#xff08;&#xff09; HAL_GPIO_WritePin&#xff08;&#xff09; 函数声明 GPIOx GPIO_Pin PinState HAL_GPIO_TogglePin&…

538页21万字数字政府大数据云平台项目建设方案

2 项目建设需求 2.1 项目建设目标 2.2 项目建设内容 2.3 项目建设要求 2.3.1 基础设施服务建设 2.3.2 信息安全服务建设 2.3.3 运行保障服务建设 2.3.4 业务应用支撑建设 3 平台建设方案 3.1 总体建设原则 3.2 总体方案设计 3.2.1 方案设计思路 3.2.2 总体架构设计 …

Spark RDD编程模型及算子介绍(二)

文章目录常见的Action算子常见分区操作算子常见的Action算子 countByKey算子&#xff1a;统计Key出现的次数&#xff0c;部分代码如下&#xff1a; rdd_file sc.textFile("../Data/input/words.txt") rdd_map rdd_file.flatMap(lambda line: line.split(" &…

Mybatis拦截器源码详解

Mybatis拦截器源码详解Mybatis相关全览一、简介执行与添加顺序拦截器生效入口二、使用例子三、原理加载入口生成代理遍历拦截器匹配&生成代理四、实践例子本文用的是3.5.10版本 源码地址&#xff1a;https://github.com/mybatis/mybatis-3/releases 文档地址&#xff1a;ht…

【云原生监控系列第三篇】Prometheus普罗米修斯进阶——PromQL的指标类型

目录一、PromQL 的指标类型1.1 Counter1.2 Gauge1.3 Histogram1.4 Summary1.5 Histogram 与 Summary 的异同二、Prometheus 的聚合函数三、PromQL 的聚合表达式一、PromQL 的指标类型 PromQL 有四个指标类型&#xff1a; Counter &#xff1a;计数器&#xff0c;用于保存单调递…

医疗产品设计的重要性,你了解多少?

医疗产品设计直接关系患者生活的方式与治疗&#xff0c;一个好的医疗产品设计不但要逐渐细化、便于实际操作&#xff0c;而且还要有利于医师操纵&#xff0c;让患者觉得舒服。这是一种具备重大意义的产品。让我们一起来看看有关医疗产品设计的具体内容! 什么叫医疗产品设计? 医…

【Java技术专题】「原理分析系列」Lambda表达式实现原理分析

Lamdba表达式起源 java8引入了lambda表达式是我们java编程方式变革的一个伟大的创举&#xff0c;由了它我们可以采用闭包的形式区开发任何想开发的方法&#xff0c;让java程序与C或者C更加有了贴合的感觉&#xff0c;虽然编程方式和我们目前的命令式编程方式有很大的不同&#…

仿真必修课:计算电磁学入门(附件参考文献与笔记)

转载自电磁CAEer &#xff0c;作者&#xff1a;刘兵 “作为一个电磁设计师&#xff0c;有必要了解计算电磁学吗&#xff1f;” 答案是肯定的。电磁计算从业人员按照分工大致可以分为两类&#xff1a;一类从事CEM&#xff08;计算电磁学&#xff09;&#xff0c;一类从事CAE&a…

ROS 开源项目 TurtleBot3 安装与使用

功能介绍 启动slam完成地图的搭建与保存启动navigation并读取保存的地图&#xff0c;完成自动导航。 注&#xff1a;人工咨询 如果按照下面方案也无法成功解决&#xff0c;可以进入我淘宝咨询&#xff0c;可进行远程辅助解决。 1、安装部分 1.1 创建工作空间lee_ws mkdir…

java项目-第140期ssm高校二手交易平台-ssm毕业设计_计算机毕业设计

java项目-第140期ssm高校二手交易平台-ssm毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm高校二手交易平台》 该项目分为2个角色&#xff0c;管理员和用户。 用户在前台浏览商品&#xff0c;并且可以进行购买。用户购买后可以在后台查看自己的订单等…

论文阅读-基于低秩分解的网络异常检测综述

论文地址&#xff1a;基于低秩分解的网络异常检测综述 摘要&#xff1a; 异常检测对于网络管理与安全至关重要&#xff0e;国内外大量研究提出了一系列网络异常检测方法,其 中大多数方法更关注数据包及其独立时序数据流的分析、检测与告警,这类方法仅仅利用了网络数据之 间的…

嵌入式分享合集104

一、不用串口&#xff0c;如何打印STM32单片机log 本文主要介绍在嵌入式开发中用来输出log的方法。 最常用的是通过串口输出uart log&#xff0c;这种方法实现简单&#xff0c;大部分嵌入式芯片都有串口功能。但是这样简单的功能有时候却不是那么好用&#xff0c;比如&#xf…

入门 Activiti 工作流,通俗易懂

概念 工作流。通过计算机对业务流程自动化执行管理&#xff0c;主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程&#xff0c;从而实现某个预期的业务目标&#xff0c;或者促使此目标的实现”。 Activiti7 介绍 Activiti是一个工作…

Spring启动流程

Spring启动流程 按Bean状态描述&#xff1a; 创建Bean工厂对Bean工厂后置处理通过Component和Import扫描BeanDefinition&#xff0c;加入到Bean工厂注册Bean后置处理器&#xff0c;用于拦截Bean创建实例化填充属性初始化 调用aware方法BeanPostProcessor实例化前执行调用初始…

【java进阶01:final关键字】final修饰的变量只能赋一次值

目录 final修饰的类无法继承。 final修饰的引用一旦指向某个对象&#xff0c;则不能再指向其他对象&#xff0c;但该引用指向的对象内部的数据是可以修改的。​编辑 final修饰的实例变量必须手动初始化&#xff0c;因为系统不会赋默认值&#xff0c;强制手动赋值&#xff0c…

【router-view】切换组件 深刻理解用法 vue的设计思想

之前学的时候没学明白&#xff0c;导致写项目有些功能的实现上走了歪路。 今天询问了学长&#xff0c;更加深刻的理解的Vue的设计思想。 因为vue是单页面应用&#xff0c;所以学会用router-view来切换频繁变化的地方的组件是非常重要的。 之前&#xff0c;我的一个主页组件由…

Xshell远程连接配置 Ubuntu 18.04.6 + Anaconda + CUDA + Cudnn + Pytorch(GPU+CPU)

Xshell远程连接进行Ubuntu的Pytorch配置写在最前面参考Xshell常用命令Ubantu检查系统的各项配置查看ubuntu系统的版本信息查看Linux的内核版本和系统是多少位的Ubuntu版本各种验证禁用nouveau安装显卡驱动卸载显卡驱动安装显卡驱动加入PPA&#xff0c;然后更新库方法一&#xf…

maven离线模式及设置

maven离线模式及设置 maven离线模式使用场景&#xff1f; 遇到的问题&#xff1a; 最近遇到个项目支持&#xff0c;他在打jar包的时候&#xff0c;总是去网上下载 maven依赖&#xff0c;不去找我本地仓库的&#xff0c;就比较头大&#xff0c;原因不明 现在需求&#xff1a;就…

SpringBoot 玩一玩代码混淆,防止反编译代码泄露

编译 简单就是把代码跑一哈&#xff0c;然后我们的代码 .java文件 就被编译成了 .class 文件 反编译 就是针对编译生成的 jar/war 包 里面的 .class 文件 逆向还原回来&#xff0c;可以看到你的代码写的啥。 比较常用的反编译工具 JD-GUI &#xff0c;直接把编译好的jar丢进…