数据结构:二叉树—面试题(一)

目录

1、相同的树

2、另一棵树的子树

3、翻转二叉树

4、平衡二叉树 

 5、对称二叉树

 6、二叉树遍历

7、二叉树的分层遍历


1、相同的树

习题链接https://leetcode.cn/problems/same-tree/description/

描述:

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

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

解题思路 

根据题意,他要我们判断这两棵树是否相同,我们知道要判断两棵树是否相同,就是要判断树的结构和对应结点的内容是否相同

首先我们要来看,给我们的两棵树是否是一棵树有结点,一棵树没有结点,如果是这样的话,我们就认为这两棵树不相同,同时如果这两颗树的根节点都为空,那么我们就认为,这两棵树相同。

经历了这两个条件后,此时的这两颗树一定是都存在结点,这时我们在判断此时的根节点值是否相同,如果不同,就是不相同的树,如果相同,我们就继续往下走,判断对应的左子树和右子树是否相同,在递归的形势下,传入两棵树根的左边结点作为新的根节点,进行判断,同理右边也是一样。在这种情况下完成对两棵树的结构和内容的判断。

完整代码

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;
        }

        if(p.val != q.val){
            return false;
        }
        return isSameTree(p.left,q.left) && isSameTree(p.right ,q.right);
    }
}

2、另一棵树的子树

习题链接https://leetcode.cn/problems/subtree-of-another-tree/

描述:

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

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

解题思路 

根据题意,他是要我们判断给出的两棵树中一棵是否为另一棵的子树,而这个子树是包含某个结点开始和他所有的后代的,这样来看其实就是判断一棵树的子树和他给出的另一棵树是否相同。(注意:如果两棵树从根节点开始就是相同的,我们也认为他符合题意

首先,我们从根节点开始进行判断,我们要先判断我们的根节点是否为空,因为在下面我们是要有递归实现的总有一次我们会递归到为空的时候,这就代表我们此时的根节点为空,而我们要判断的subRoot这棵树却不为空,这就代表了以此时结点为根节点的树是和我们要判断的树是不同的,因此我们要返回false.而我们判断的方法就是我们上面写的题相同的树,因此我们将根节点传isSameTree进行判断。

当我们判断完根结点后我们要判断跟的左子树,因此我们要将根的左结点传入进行递归,判断完再判断右树,如果都不存在就返回false;

完整代码

class Solution {
    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;
    }

    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;
        }
        if(p.val != q.val){
            return false;
        }
        return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);

    }
}

3、翻转二叉树

习题链接https://leetcode.cn/problems/invert-binary-tree/description/

描述:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 

解题思路 

根据图示我们能发现这道题就是让我们将根的左右结点进行交换,说到交换这就简单了,想必大家都理解,而他是要交换整棵树因此我们交换完根节点后,还要交换他左子树的结点和右子树的结点,因此我们可以利用递归传入根的左右结点,再继续往下找左右结点进行交换。

完整代码

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

4、平衡二叉树 

习题链接https://leetcode.cn/problems/balanced-binary-tree/description/

描述:给定一个二叉树,判断它是否是 平衡二叉树

   

解题思路 

首先我们要先来了解什么是平衡二叉树,所谓平衡二叉树就是,一个根节点左边的长度和右边的长度的差值要小于等于1.

而根据对平衡二叉树的了解,我们发现我们应该去求他左子树和右子树的长度,让他们相减。

关于二叉树长度的计算我们再二叉树中已经进行了讲解,大家可以去看看。数据结构:二叉树

因为我们要判断整棵树是否为平衡二叉树,因此我们要从根结点判断是否为平衡二叉树,还要对子树的子树进行平衡二叉树的判断,如果都是平衡二叉树,我们就认为他是平衡二叉树,对于这样的判断我们就要用到递归的方式来进行了。

因此我们获得根结点的左右子树长度进行相减并且利用递归传入根的左结点和右结点进行子树的子树判断

完整代码

class Solution {
    public boolean isBalanced(TreeNode root) {
        if(root == null){
            return true;
        }
        int leftMax = getH(root.left);
        int rightMax = getH(root.right);
        return Math.abs(leftMax - rightMax) <=1 && isBalanced(root.left) && isBalanced(root.right);

    }
    public int getH(TreeNode root){
        if(root == null){
            return 0;
        }
        int leftH = getH(root.left);
        int rightH = getH(root.right);
        return Math.max(leftH,rightH)+1;
    }
}

 5、对称二叉树

习题链接https://leetcode.cn/problems/symmetric-tree/description/ 

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

解题思路 

这道题其实和我们第1题是相同的,我们还是判断是否相同,只是从两棵树的判断,到了一棵树左右子树的判断,当时我们要注意因为他要判断是否为镜像,因此,我们判断是否相同是要判断一棵子树的左边和另一棵子树的右边,一棵子树的右边和另一棵子树的左边是否结构相同内容相同

完整代码

class Solution {
    public boolean isSymmetric(TreeNode root) {
        if(root == null){
            return true;
        }
        return isSameTree(root.left,root.right);
    }
     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;
        }
        if(p.val != q.val){
            return false;
        }
        return isSameTree(p.left,q.right) && isSameTree(p.right,q.left);
     }
}

 6、二叉树遍历

习题链接https://www.nowcoder.com/practice/4b91205483694f449f94c179883c1fef?tpId=60&&tqId=29483&rp=1&ru=/activity/oj&qru=/ta/tsing-kaoyan/question-ranking

描述: 

编一个程序,读入用户输入的一串先序遍历字符串,根据此字符串建立一个二叉树(以指针方式存储)。 例如如下的先序遍历字符串: ABC##DE#G##F### 其中“#”表示的是空格,空格字符代表空树。建立起此二叉树以后,再对二叉树进行中序遍历,输出遍历结果。

输入描述:

输入包括1行字符串,长度不超过100。

输出描述:

可能有多组测试数据,对于每组数据, 输出将输入字符串建立二叉树后中序遍历的序列,每个字符后面都有一个空格。 每个输出结果占一行。 

 

解题思路 

根据题意,我们知道他是要我们根据先序遍历,建立一棵二叉树,再输出二叉树的中序遍历。

首先我们要根据先序遍历创建二叉树,在创建二叉树前我们要创建结点,因为二叉树是由一个个结点形成的。

创建完结点后,我们就要创建二叉树,我们知道先序遍历的顺序是:根左右,因此我们要先创建完左子树再创建右子树,那么什么时候我们停止创建左子树呢?

停止的时刻其实是当我们遇到空树的时候,而先序遍历给我们的空树就是“#”,因此只要我们没遇到“#”,就创建左子树,并让先序遍历往下走,遇到“#”了我们就停止,但依然让先序遍历往下走,并返回到上面一层,去创建右子树。

当右子树也遇到“#”了,我们就停止创建二叉树,但依然让先序遍历往下走,并返回到上面一层,此时左右子树都走完了再返回上一层,去创建右子树,在这样不断的递归和返回就成功创建了二叉树。

当我们创建完二叉树后,接下来就是用中序遍历去打印了(左根右)

完整代码

import java.util.Scanner;
class TreeNode{
    char val;
    TreeNode left;
    TreeNode right;
    public TreeNode(char val){
        this.val = val;
    } 
}
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static int i = 0;
    public static TreeNode createTree(String str){
        TreeNode root = null;
        if(str.charAt(i) != '#'){
            root = new TreeNode(str.charAt(i));
            i++;
            root.left = createTree(str);
            root.right = createTree(str);
        }else{
            i++;
        }
        return root;
    }
    public static void oread(TreeNode root){
        if(root == null){
            return;
        }
        oread(root.left);
        System.out.print(root.val + " ");
        oread(root.right);
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
           String str = in.nextLine(); 
           TreeNode root = createTree(str);
           oread(root);
       }
    }
}

7、二叉树的分层遍历

习题链接https://leetcode.cn/problems/binary-tree-level-order-traversal/description/

描述:

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

解题思路 

这道题就是让我将二叉树由层序遍历输出,而层序遍历的方式我们再上一篇二叉树是已经进行了讲解大家可以去看看,数据结构:二叉树

而这道虽然仍是以层序遍历输出,但是他输出要求是同一层的放到一起输出

因此我们可以在层序遍历的基础上再创建一个链表curList,然后再计算次数队列的长度根据长度决定出队的个数,并让出队的元素放到链表curList中,并将此时出队的元素左右结点放入队列中,当这个循环结束了就代表上一个队列为空了,再将curList的值放入到list链表中,然后利用循环再判断此时的队列,再创建一个新的curList重复上面的操作,这样就实现了同一层的放到一起输出

完整代码

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> list = new ArrayList<>();
        if(root == null){
            return list;
        }
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        while(!q.isEmpty()){
            List<Integer> curList = new ArrayList<>();
            int size = q.size();
            while(size != 0){
                TreeNode cur = q.poll();
                curList.add(cur.val);
                if(cur.left != null){
                    q.offer(cur.left);
                }
                if(cur.right != null){
                    q.offer(cur.right);
                }
                size--;
            }
            list.add(curList); 
        }
        return list;
    }
}

好了。今天的分享就到这里了,还请大家多多关注,我们下一篇再见!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

绘制决策树尝试2 内含添加环境变量步骤

目录 step1 ai码 ai改 step2 下面就是环境配置问题 “ExecutableNotFound: failed to execute WindowsPath(‘dot’), make sure the Graphviz executables are on your systems’ PATH” dot -v愣是没有​编辑 graphviz安装指导 对于Windows用户&#xff1a; 对于Lin…

基于迁移学习的ResNet50模型实现石榴病害数据集多分类图片预测

完整源码项目包获取→点击文章末尾名片&#xff01; 番石榴病害数据集 背景描述 番石榴 &#xff08;Psidium guajava&#xff09; 是南亚的主要作物&#xff0c;尤其是在孟加拉国。它富含维生素 C 和纤维&#xff0c;支持区域经济和营养。不幸的是&#xff0c;番石榴生产受到降…

C++17 命名空间的新特性:简化与优化的典范

文章目录 1. 简化的嵌套命名空间1.1 背景与问题1.2 C17的解决方案1.3 实际应用场景1.4 注意事项 2. 声明多个名称的using声明2.1 背景与问题2.2 C17的解决方案2.3 实际应用场景2.4 注意事项 3. 属性命名空间的简化3.1 背景与问题3.2 C17的解决方案3.3 实际应用场景3.4 注意事项…

【JavaEE】-- 计算机是如何工作的

文章目录 1. 冯诺依曼体系&#xff08;VonNeumann Architecture)2. CPU 基本工作流程2.1 寄存器(Register)和 内存(RAM)2.2 控制单元 CU(ControlUnit)2.3 指令&#xff08;Instruction) 3. 操作系统&#xff08;OperatingSystem)3.1 操作系统的定位3.2 什么是进程/任务(Process…

消融效果

消融效果是模拟物体逐渐从屏幕上消失或溶解的过程&#xff0c;它通常利用噪声纹理实现&#xff0c;使物体按照某种规则逐渐透明或完全不可见。这种效果常用于&#xff1a; 角色死亡、传送场景、 魔法消失&#xff0c;比如燃烧、消失等 1、基本原理 通过对比噪声纹理值与消融进…

java后端之事务管理

Transactional注解&#xff1a;作用于业务层的方法、类、接口上&#xff0c;将当前方法交给spring进行事务管理&#xff0c;执行前开启事务&#xff0c;成功执行则提交事务&#xff0c;执行异常回滚事务 spring事务管理日志&#xff1a; 默认情况下&#xff0c;只有出现Runti…

【Paper Tips】随记2-word版快速删除某字符

写paper时随心记录一些对自己有用的skills与tips。 文章目录 一、待解决问题1.1 问题描述1.2 解决方法 二、方法详述2.1 必要说明2.2 应用步骤2.2.1 CtrlH一键全文替换2.2.2 录制宏 三、疑问四、总结 一、待解决问题 1.1 问题描述 word中粘贴部分文字时&#xff0c;格式不对时…

vite环境变量处理

环境变量: 会根据当前代码环境产生值的变化的变量就叫做环境变量 代码环境: 开发环境测试环境预发布环境灰度环境生产环境 举例: 百度地图 SDK,小程序的SDK APP_KEY: 测试环境和生产环境还有开发环境是不一样的key 开发环境: 110 生产环境:111 测试环境: 112 我们去请求第三…

使用JavaScript实现猜数字小功能

引言&#xff1a; 在学习编程的过程中&#xff0c;通过实际的小项目来巩固知识是非常有效的方法。今天&#xff0c;我们将使用 JavaScript 来实现一个简单的猜数字游戏。这个游戏不仅能让我们熟悉 JavaScript 的基本语法&#xff0c;还能锻炼我们的逻辑思维能力。 游戏规则 …

数据结构——概念与时间空间复杂度

目录 前言 一相关概念 1什么是数据结构 2什么是算法 二算法效率 1如何衡量算法效率的好坏 2算法的复杂度 三时间复杂度 1时间复杂度表示 2计算时间复杂度 2.1题一 2.2题二 2.3题三 2.4题四 2.5题五 2.6题六 2.7题七 2.8题八 四空间复杂度 1题一 2题二 3…

【转帖】eclipse-24-09版本后,怎么还原原来版本的搜索功能

【1】原贴地址&#xff1a;eclipse - 怎么还原原来版本的搜索功能_eclipse打开类型搜索类功能失效-CSDN博客 https://blog.csdn.net/sinat_32238399/article/details/145113105 【2】原文如下&#xff1a; 更新eclipse-24-09版本后之后&#xff0c;新的搜索功能&#xff08;CT…

Django基础之ORM

一.前言 上一节简单的讲了一下orm&#xff0c;主要还是做个了解&#xff0c;这一节将和大家介绍更加细致的orm&#xff0c;以及他们的用法&#xff0c;到最后再和大家说一下cookie和session&#xff0c;就结束了全部的django基础部分 二.orm的基本操作 1.settings.py&#x…

单片机-STM32 IIC通信(OLED屏幕)(十一)

一、屏幕的分类 1、LED屏幕&#xff1a; 由无数个发光的LED灯珠按照一定的顺序排列而成&#xff0c;当需要显示内容的时候&#xff0c;点亮相关的LED灯即可&#xff0c;市场占有率很高&#xff0c;主要是用于户外&#xff0c;广告屏幕&#xff0c;成本低。 LED屏是一种用发光…

纯css实现div宽度可调整

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>纯css实现div尺寸可调整</title><style…

国产编辑器EverEdit - 输出窗口

1 输出窗口 1.1 应用场景 输出窗口可以显示用户执行某些操作的结果&#xff0c;主要包括&#xff1a; 查找类&#xff1a;查找全部&#xff0c;筛选等待操作&#xff0c;可以把查找结果打印到输出窗口中&#xff1b; 程序类&#xff1a;在执行外部程序时(如&#xff1a;命令窗…

小游戏源码开发搭建技术栈和服务器配置流程

近些年各种场景小游戏开发搭建版本层出不穷,山东布谷科技拥有多年海内外小游戏源码开发经验&#xff0c;现为从事小游戏源码开发或游戏运营的朋友们详细介绍小游戏开发及服务器配置流程。 一、可以对接到app的小游戏是如何开发的 1、小游戏源码开发的需求分析&#xff1a; 明…

Linux C\C++编程-文件位置指针与读写文件数据块

【图书推荐】《Linux C与C一线开发实践&#xff08;第2版&#xff09;》_linux c与c一线开发实践pdf-CSDN博客 《Linux C与C一线开发实践&#xff08;第2版&#xff09;&#xff08;Linux技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 Linu…

一文简单回顾复习Java基础概念

还是和往常一样&#xff0c;我以提问的方式回顾复习&#xff0c;今天回顾下Java小白入门应该知道的一些基础知识 Java语言有哪些特点呢&#xff1f; Java语言的特点有&#xff1a; 面向对象&#xff0c;主要是封装、继承、多态&#xff1b;平台无关性&#xff0c;“一次编写…

Redis实战(黑马点评)——关于缓存(缓存更新策略、缓存穿透、缓存雪崩、缓存击穿、Redis工具)

redis实现查询缓存的业务逻辑 service层实现 Overridepublic Result queryById(Long id) {String key CACHE_SHOP_KEY id;// 现查询redis内有没有数据String shopJson (String) redisTemplate.opsForValue().get(key);if(StrUtil.isNotBlank(shopJson)){ // 如果redis的数…

神经网络|(四)概率论基础知识-古典概型

【1】引言 前序学习了线性回归的基础知识&#xff0c;了解到最小二乘法可以做线性回归分析&#xff0c;但为何最小二乘法如此准确&#xff0c;这需要从概率论的角度给出依据。 因此从本文起&#xff0c;需要花一段时间来回顾概率论的基础知识。 【2】古典概型 古典概型是我…