二叉树基础oj题目

news2024/9/19 10:47:48

二叉树基础oj题目及思路总结

前文中,介绍了二叉树的基本概念及基础操作,进一步对于二叉树的递归遍历及子问题的处理思想有了一定的了解。本文将带来几道二叉树经典的oj题目。

目录

二叉树基础oj题目

  • 对称二叉树
  • 平衡二叉树
  • 二叉树的层序遍历

二叉树基础oj题目

1、对称二叉树

leetcode题目链接
题目描述:给你一个二叉树的根节点 root , 检查它是否轴对称。如下图就是一颗对称二叉树:
在这里插入图片描述
我们可以模拟判断二叉树是不是对称二叉树:
1、对于结点1,左孩子结点为2,右孩子结点为2,目前是对称二叉树。
2、对于1的左孩子结点2,左孩子结点为3,右孩子结点为4, 对于1的右孩子结点2,右孩子结点3,左孩子结点为4,左与右对应,右与左对应,仍是对称二叉树。
可以发现,只要将右子树翻转(左到右,右到左)判断是否与左树相同即可。在总体框架上,仍然使用递归(子问题思路)的方式实现。

 public boolean isSymmetric(TreeNode root) {
        if(root==null) {
            return false;
        }
        return isSameTree(root.left,invertTree(root.right));
    }
    public TreeNode invertTree(TreeNode root) {//翻转二叉树
        if(root==null) return null;
        TreeNode tep = root.left;//引入tmp结点交换左右结点
        root.left = root.right;
        root.right = tep;
        invertTree(root.left);//递归实现子树的翻转
        invertTree(root.right);
        return root;
    }
     public boolean isSameTree(TreeNode p, TreeNode q) {//判断左右树是否相同
        if(p==null&&q!=null||q==null&&p!=null) {//一个为空,一个不为空必不同
            return false;
        }
        if(p==null&&q==null) {
            return true;
        }
        if(p.val!=q.val) {//值不同,结点必不同
            return false;
        }
        return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);//递归模拟遍历树
    }

2、平衡二叉树

leetcode题目链接
给定一个二叉树,判断它是否是高度平衡的二叉树。本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。下图就是一颗平衡二叉树。
在这里插入图片描述
这道题目有两个思路:

  • 1、自顶向下的递归
  • 2、自底向上的递归

对于自顶向下的递归,需要对于当前遍历到的节点,首先计算左右子树的高度,如果左右子树的高度差不超过1,再分别递归地遍历左右子节点,并判断左子树和右子树是否平衡。这是一个自顶向下的递归的过程。这种递归需要计算每一个结点的高度,时间复杂度较高,为O(N^2)。

而对于自底向上的递归,可以递归地判断其左右子树是否平衡,再判断以当前节点为根的子树是否平衡。如果一棵子树是平衡的,则返回其高度(高度一定是非负整数),否则返回 −1。**如果存在一棵子树不平衡,则整个二叉树一定不平衡。**这种递归方式较为高效,时间复杂度为O(N)。

它们之间的根本区别就是自底向上的递归相较于自顶向下的递归,能够记录下底部的结点构成的子树是不是平衡的,一旦不平衡,就可以直接返回-1,得到这棵树不平衡的结论,可以省去在递归过程中许多重复的计算。下面给出自底向上的递归的代码:

public boolean isBalanced(TreeNode root) {
        return height(root) >= 0;//不平衡height()返回的是-1
    }

    public int height(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        if (leftHeight == -1 || rightHeight == -1 //左右子树已经不都平衡,直接返回-1
        || Math.abs(leftHeight - rightHeight) > 1) {//从高度上判断树不平衡,返回-1
            return -1;
        } else {
            return Math.max(leftHeight, rightHeight) + 1;//该结点的子树仍平衡,返回最大深度
        }
    }

3、二叉树的层序遍历

leetcode题目链接
给你二叉树的根节点 root ,返回其节点值的 层序遍历。(即逐层地,从左到右访问所有节点)。
如下图所示。
在这里插入图片描述
要解决这个问题,似乎我们不能直接通过递归遍历的方式解决。思考一下,第二层的结点都是第一层的根的孩子结点,第三层的根都是第二层的根的孩子结点…而我们打印的顺序也是从上往下打印,有一种先进先出的感觉,这是我们可以考虑使用队列这种数据结构解决问题。
思路:
**对于第一个结点:1、为空,直接return返回。2、不为空,进入队列。
1、循环条件:队列不为空。2、获取队列长度size。3、判断刚入队结点的左孩子结点与右孩子结点,将不为空的结点入队列。4、将size个结点出队列,并输出这些结点的值。当队列为空时,输出结束。**下面是具体代码的呈现:

public List<List<Integer>> levelOrder(TreeNode root) {//返回的实际上是一个二维数组
        List<List<Integer>> list = new ArrayList<>();
        if(root==null) {
            return list;
        }
        Queue<TreeNode> q = new LinkedList<>();//队列中放的是结点,泛型规定为TreeNode
        q.offer(root);
        while(!q.isEmpty()) {//队列不为空
            List<Integer> l = new ArrayList<>();
            int size = q.size();//获取队列长度
            while(size!=0) {
                TreeNode cur = q.poll();
                l.add(cur.val);
                if(cur.left!=null) {//判断左孩子是否为空
                    q.offer(cur.left);
                }
                if(cur.right!=null) {//判断右孩子是否为空
                    q.offer(cur.right);
                }
                size--;
            }
            list.add(l);//将一维顺序表加到list中
        }
        return list;
    }

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

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

相关文章

(C语言)编译和链接

前言͟͟͞͞&#x1f48c;&#xff1a;对于现在的各种编译器而言许多都是好多个功能的集成&#xff0c;那么我们的代码到底是如何去实现的呢&#xff1f;难道我们的计算机可以直接读懂我们所写的代码&#xff0c;并运行吗&#xff1f;对于很多细心的小伙伴们可能会想这样的问题…

强缓存、协商缓存(浏览器的缓存机制)是么子?

文章目录 一.为什么要用强缓存和协商缓存&#xff1f;二.什么是强缓存&#xff1f;三.什么是协商缓存&#xff1f;四.总结 一.为什么要用强缓存和协商缓存&#xff1f; 为了减少资源请求次数&#xff0c;加快资源访问速度&#xff0c;浏览器会对资源文件如图片、css文件、js文…

Spring DI

目录 什么是依赖注入 属性注入 构造函数注入 Setter 注入 依赖注入的优势 什么是依赖注入 依赖注入是一种设计模式&#xff0c;它通过外部实体&#xff08;通常是容器&#xff09;来注入一个对象的依赖关系&#xff0c;而不是在对象内部创建这些依赖关系。这种方式使得对象…

【Python学习】Python学习21- 正则表达式(2)

目录 【Python学习】Python学习21- 正则表达式&#xff08;2&#xff09; 前言字符串检索和替换repl 参数是一个函数参考 文章所属专区 Python学习 前言 本章节主要说明Python的正则表达式。 正则表达式是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与…

『 C++ - STL』map与set的封装 ( 万字 )

文章目录 &#x1f3a1; map与set介绍&#x1f3a1; map与set的基础结构&#x1f3a1; 红黑树的再修改&#x1f3a0;节点及树的定义&#x1f3a0;KeyOfValue的使用&#x1f3a0;插入函数&#x1f3a0;析构函数&#x1f3a0;红黑树完整代码(供参考) &#x1f3a1; 迭代器的实现&…

【C++】—— C++的IO流

在C中&#xff0c;I/O流是一项关键的编程概念&#xff0c;为程序提供了与外部世界进行交互的重要手段。通过使用C的强大I/O库&#xff0c;开发者能够实现对标准输入输出、文件、字符串等多种数据源的高效处理。接下来让我们深入探讨C的I/O流&#xff0c;了解其基本原理、常见操…

基于动态顺序表实现通讯录项目

本文中&#xff0c;我们将使用顺序表的结构来完成通讯录的实现。 我们都知道&#xff0c;顺序表实际上就是一个数组。而使用顺序表来实现通讯录&#xff0c;其内核是将顺序表中存放的数据类型改为结构体&#xff0c;将联系人的信息存放到结构体中&#xff0c;通过对顺序表的操…

GO 中高效 int 转换 string 的方法与高性能源码剖析

文章目录 使用 strconv.Itoa使用 fmt.Sprintf使用 strconv.FormatIntFormatInt 深入剖析1. 快速路径处理小整数2. formatBits 函数的高效实现 结论 Go 语言 中&#xff0c;将整数&#xff08;int&#xff09;转换为字符串&#xff08;string&#xff09;是一项常见的操作。 本文…

数据库-数据库分类

数据库可以分为关系型数据库和非关系型数据库&#xff0c;常见的数据库如下 关系型数据库 关系型数据库是一种采用关系模型来组织数据的数据库&#xff0c;它以行和列的形式存储数据&#xff0c;以便于用户理解。关系型数据库中的数据以二维表的形式组织&#xff0c;被称为表…

从零开始c++精讲:第三篇——内存管理

文章目录 一、C/C内存分布二、C语言中动态内存管理方式:malloc/calloc/realloc/free三、C中动态内存管理四、operator new与operator delete函数4.1 operator new与operator delete函数&#xff08;重点&#xff09; 五、new和delete的实现原理5.1内置类型5.2 自定义类型 六、定…

C++总结笔记

1. 简介 1、面向对象程序设计 面向对象的四大特性 1&#xff09;封装 2&#xff09;继承 3&#xff09;多态 4&#xff09;抽象 2、标准库 标准C由三个部分组成 1&#xff09;核心语言&#xff1a;提供了所有的构件块 2&#xff09;C标准库&#xff1a;提供了大量的函…

web蓝桥杯真题--11、蓝桥知识网

介绍 蓝桥为了帮助大家学习&#xff0c;开发了一个知识汇总网站&#xff0c;现在想设计一个简单美观的首页。本题请根据要求来完成一个首页布局。 准备 开始答题前&#xff0c;需要先打开本题的项目代码文件夹&#xff0c;目录结构如下&#xff1a; ├── css │ └──…

浅谈ARP协议

ARP是 address resolution protocol的缩写&#xff0c;意思是地址解析协议&#xff0c;处于OSI七层模型的网络层&#xff0c;它的作用是根据Ip地址找到mac地址&#xff0c;实际上我们需要访问某一个ip时&#xff0c;是要先找到它的mac地址&#xff0c;也就是物理地址才行的&…

Windows系统下使用docker-compose安装mysql8和mysql5.7

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十四&#xff09;——Windows系统下使用docker安装mysql8和mysql5.7 文章目录 win系统环境搭建&#xff08;十四&#xff09;——Windows系统下使用docker安装mysql8和mysql5.7MySQL81.新建文件夹2.创建…

C++播放音乐:使用EGE图形库

——开胃菜&#xff0c;闲话篓子一大片 最近&#xff0c;我发现ege图形库不是个正经的图形库—— 那天&#xff0c;我又在打趣儿地翻代码时&#xff0c;无意间看到了这个&#xff1a; 图形库&#xff1f;&#xff01;你哪来的音乐&#xff08;Music&#xff09;呢&#xff1f…

【蓝桥备赛】求阶乘

题目链接 求阶乘 个人想法 之前做过计算阶乘结果后面有几个0的题目&#xff0c;这里看到本题之后&#xff0c;很快就有思路了。想要得到阶乘结果有几个0&#xff0c;首先尾数后面的0&#xff0c;最小肯定是因为因子中存在10。然后&#xff0c;10如何得来呢&#xff1f; 2 * …

【LeetCode】141. 环形链表

leetcode题目链接 141. 环形链表 #include <stdio.h> #include <stdbool.h>struct ListNode {int val;struct ListNode* next; }; typedef struct ListNode ListNode;bool hasCycle(ListNode* head) {ListNode* slow head, * fast head;while (fast &&…

SpringBoot 3.1.7 集成Mybatis

一、介绍 Mybatis的中文官网并没找到与SpringBoot最新的集成的教程&#xff0c;有的都是老式的配置方法&#xff0c;所以记录一下怎么我是怎么集成SpringBoot 3.1.7 集成Mybatis 的方法 有条件的可以打开源网站 https://github.com/mybatis/spring-boot-starter 没有条件的我…

一款满足基层医疗机构各类业务需要的:健康云HIS系统源码,功能包括病患问诊、电子病历、开药发药、住院管理、护理文书、病案管理等功能。

一款满足基层医疗机构各类业务需要的健康云HIS系统。该系统能帮助基层医疗机构完成日常各类业务&#xff0c;提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、护理文书、病案管理、统计查询、医生站和护士站等一系列常规功能&#xff0c;能与公卫、PACS等各类外部系…

C++-类和对象(3)

1. 再谈构造函数 1.1 构造函数体赋值 我们在创建一个对象时&#xff0c;编译器会调用该对象的构造函数对该对象的成员进行初始化。 class Date { public:Date(int year, int month, int day){_year year;_month month;_day day;} private:int _year;int _month;int _day…