数据结构在二叉树Oj中利用子问题思路来解决问题

news2024/11/22 15:25:20

二叉树Oj题

  • 获取二叉树的节点数
  • 获取二叉树的终端节点个数
  • 获取k层节点的个数
  • 获取二叉树的高度
  • 检测为value的元素是否存在
  • 判断两颗树是否相同
  • 判断是否是另一棵的子树
  • 反转二叉树
  • 判断一颗二叉树是否是平衡二叉树
    • 时间复杂度O(n*n)
    • 复杂度O(N)
  • 二叉树的遍历
  • 判断是否是对称的二叉树
  • 二叉树的层序遍历

获取二叉树的节点数

首先从左树开始递到最下一层,当最后一层H没有节点时,归回+1以此类推,最终返回的节点就是我们树的节点树。
在这里插入图片描述

public int getNodeCount(TreeNode root){
        if(root==null)return 0;
        return getNodeCount(root.left)+getNodeCount(root.right)+1;
    }

获取二叉树的终端节点个数

首先清楚二叉树的终端结点是什么?
终端结点说明它的度为0(没有子树),所以左树和右树的值为null,而我们就只需要判断一下,如果左树和右树值为null,则就是一个叶子结点+1.
在这里插入图片描述

 public int getLeafCount(TreeNode root){
        if(root==null)return 0;
        if(root.left==null&&root.right==null){
            return 1;
        }
        return getLeafCount(root.left)+getLeafCount(root.right);
    }

获取k层节点的个数

第一层为我们的根节点,它的个数一定是1,而根的左树和右树则为2,以此类推
在这里插入图片描述
首先我们的第一个条件是k为1时一定会有一个节点数
这里当我们递出去时,我们就会减少一层当k等于1时,这里我们就在k层找到一个节点然后回归到父节点然后继续子树找下一个节点,知道将k层的节点数遍历完。
在这里插入图片描述

  public int getLevelCount(TreeNode root,int k){
        if(root==null)return 0;
        if(k==1)return 1;
        return getLevelCount(root.left,k-1)+getLevelCount(root.right,k-1);
    }

获取二叉树的高度

这里直接求左子树的最大高度和右子树的最大高度然后进行比较,然后返回最大的高度值就可以
在这里插入图片描述

在这里插入图片描述

  public int getBinaryTreeHeight(TreeNode root){
        if(root==null)return 0;
            int maxtLeftHeight=getBinaryTreeHeight(root.left);
            int maxRightHeight=getBinaryTreeHeight(root.right);
            return maxLeftHeight>maxRightHeight?maxLeftHeight+1:maxRightHeight+1;
    }

检测为value的元素是否存在

首先root根和递归的条件不能为空
然后判断root的值是否为value值并返回这个值
用一个ret来接收其返回值,然后判断ret不为空,则回来的值将root的value值带回
(ret如果为空,说明root根或者递归的条件就是空的,没有要找的元素)
在这里插入图片描述

public TreeNode find(TreeNode root,String val){
        if(root==null)return null;
        if(root.val.equals(val))   return root;
        TreeNode ret1 =  find(root.left,val);
        if(ret1!=null)return ret1;
        TreeNode ret2 =  find(root.right,val);
        if(ret2!=null)return ret2;
        return null;
    }

判断两颗树是否相同

判断两颗树是否相同
首先根节点到叶子结点两者的结构相同
然后是根节点到叶子结点的值要相同
如果说一棵树为空但是另一个树不为空,说明两棵树的结构一定是不同的
如果两颗树都为空,加上上述说明两棵树的结构一致
接下来判断节点的值
两颗树的节点值如果不一样,则也不是相同的
最后判断两颗树左树和右树是否一致
两棵树

   public boolean isSameTree(TreeNode tree1,TreeNode tree2){
        //两棵树如果同时走一个有节点一个没有节点一定不相同
        if(tree1==null&&tree2!=null||tree1!=null&&tree2==null)return false;
        //两棵树都为null说明都没有可以走的节点
        if(tree1==null&&tree2==null)return true;
        //判断结构
        //判断节点值是否相同不同为false
        if(!tree1.val.equals(tree2.val)return false;
        return isSameTree(tree1.left,tree2.left)&&isSameTree(tree1.right,tree2.right);
    }

判断是否是另一棵的子树

判断是否是tree中的一颗子树,subtree一定是t在ree中头节点左子树中或者是右子树中,如果不在这里直接返回false
这里由tree的左子树和右子树递归找到subtree的根节点,找到后将tree中的subtree子树与subtree同时遍历来确认是否为一个相同的树。

在这里插入图片描述

 public boolean isSubtree(TreeNode root, TreeNode subRoot) {
        //是相同的树节点返回true
        if(isSameTree(root,subRoot))return true;
        //递归如果出现root为null时,因为没有语句拦截,root会继续往下走导致空指针异常
        //subRoot为null直接返回false,主树不在进行下面的递归
        if(root==null||subRoot==null)return false;
        if(isSubtree(root.left,subRoot))return true;
        if(isSubtree(root.right,subRoot))return true;
        return false;
    }

反转二叉树

将二叉树的每个节点的左子树和右子树互换
在这里插入图片描述
在这里插入图片描述

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

判断一颗二叉树是否是平衡二叉树

时间复杂度O(n*n)

该题判断二叉树是否是平衡二叉树的条件是:左子树与右子树的绝对值一定小于或者等于1,如果高度大于1则非平衡二叉树。
如果根节点只有一个节点或者他的左右子树差的绝对值为0,则为平衡二叉树
在这里插入图片描述
只判断了根的节点的话它的左右子树的差确实为1,但是左子树中b的左子树和右子树的差值为2,这也不是一个平衡的二叉树。
在这里插入图片描述

  public boolean isBalanced(TreeNode root) {
        if(root==null)return true;//root为null直接返回为空
        int leftHeight = maxDepth(root.left);//求左树的高度
        int rightHeight = maxDepth(root.right);//求右树的高度
        return Math.abs(leftHeight-rightHeight)<=1//判断
        &&isBalanced(root.left)&&isBalanced(root.right);
    }
    public int maxDepth(TreeNode root){
        //求二叉树的最大深度
        if(root==null)return 0;
        int leftHeight=maxDepth(root.left);
        int rightHeight=maxDepth(root.right);
        return leftHeight>rightHeight?leftHeight+1:rightHeight+1;
    }

复杂度O(N)

我们如果
这里如果我们在找左右子树高度的差值时如果发现了它差值大于1的情况,我们直接返回-1,当最后回归到根节点左右子树时,差值也大于1

class Solution {
    public boolean isBalanced(TreeNode root) {
        if(root==null)return true;
        int ret =maxDepth(root);
        //接收ret为-1则左右子树差值一定大于1
        if(ret==-1){
            return false;
        }
        return true;
    }
    public int maxDepth(TreeNode root){
        //求二叉树的最大深度
        if(root==null)return 0;
        int leftHeight=maxDepth(root.left);
        int rightHeight=maxDepth(root.right);
        //走到这里最靠下的边上的左右子树求得高度
        if(leftHeight>=0&&rightHeight>=0&&Math.abs(leftHeight-rightHeight)<=1){
                //说明左右子树的绝对值为<=1并且大于等于0
                //返回左右子树中最大的一个高度+1
                return Math.max(leftHeight,rightHeight)+1;
        }else{
                return -1;
        }
        
    }
}

二叉树的遍历

在这里插入图片描述
首先创建一个类来实现构造二叉树的前提
因为题目条件给定的是输入一串字符串然后先序遍历这个字符串来建立起二叉树,然后通过中序遍历在进行打印
在这里插入图片描述

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 void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String str=in.nextLine();
            TreeNode root=createTree(str);
            inOrder(root);
        }
    }
    public static TreeNode createTree(String str) {
        TreeNode root=null;
        //遍历字符串str来获取字符来给到root,因为不确定root是不是空节点。
        if (str.charAt(i) != '#') {
            root =new TreeNode(str.charAt(i));
            i++;
            //通过i++来递归左右树
            root.left=createTree(str);
            root.right=createTree(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);
    }

判断是否是对称的二叉树

二叉树反转过来的镜像就是对称的二叉树
这里直接从根节点的左树和右树下手
满足条件1:二叉树的结构相同
满足条件2:二叉树的对称值相同
左子树中的左树对应右子树的右树
右子树的左树对应左子树的右树

在这里插入图片描述

    public boolean isSymmetric(TreeNode root) {
        if(root==null)return true;
        //判断左右节点是否对称
        return isSymmetricChild(root.left,root.right);
    }
    public boolean isSymmetricChild(TreeNode t1,TreeNode t2){
        //这里t1和t2的结构不相同
        if(t1==null&&t2!=null||t1!=null&&t2==null)return false;
        //两者都为空,说明结构相同走向空节点
        if(t1==null&&t2==null)return true;
        //到这里结构相同检查对称值
        if(t1.val!=t2.val)return false;
        //满足左右子树的对称条件 
        return isSymmetricChild(t1.left,t2.right)
        &&isSymmetricChild(t1.right,t2.left);
    }

二叉树的层序遍历

二叉树层序遍历是地1层开始从左到右,从上到下开始遍历。
如果用二维数组来进行层序遍历怎么做呢?
这里需要用到队列,因为第一层的根节点永远是1,我们将它放入到队列中来遍历这个队列

如果a释放完且a树的值给到了一维数组后,会得到b和c两个子树并放到队列中,这时候需要一个计数器来计算当前的层数,当层数为0时,我们将一维数组所有的值放到二维数组中就好了
在这里插入图片描述

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

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

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

相关文章

【C++】踏上C++学习之旅(九):深入“类和对象“世界,掌握编程的黄金法则(四)(包含四大默认成员函数的练习以及const对象)

文章目录 前言1. 实现Date类的构造函数2. 实现Date类的拷贝构造函数3. 实现Date类的赋值运算符重载4. 实现各Date对象之间的比较接口5. 实现Date对象的加减接口6. const成员7. 取地址及const取地址操作符重载 前言 在我们前面学习到了"类和对象"的四大默认成员函数(…

远程控制软件使用教程

随着数字化办公浪潮的席卷&#xff0c;远程控制软件已经悄无声息地融入我们的日常生活&#xff0c;成为提升工作效率的神奇工具。它让我们无论身处何地&#xff0c;都能轻松驾驭办公室电脑&#xff0c;让旅途中的工作也变得轻松自如。那么&#xff0c;远程控制软件究竟是什么&a…

oracle查看锁阻塞-谁阻塞了谁

一 模拟锁阻塞 #阻塞1 一个会话正在往一个大表写入大量数据的时候&#xff0c;另一个会话加字段&#xff1a; #会话1 #会话2 会话2被阻塞了。 #阻塞2 模拟一个会话update一条记录&#xff0c;没提交。 另一个会话也update这一条记录&#xff1a; 会话2被阻塞了。 二 简单查…

我用豆包MarsCode IDE 做了一个 CSS 权重小组件

作者&#xff1a;夕水 查看效果 作为一个前端开发者&#xff0c;应该基本都会用VSCode来做开发&#xff0c;所以也应该见过如下这张图的效果: 以上悬浮面板分为2个部分展示内容。 <element class"hljs-attr">: 代表元素只有一个类名叫hljs-attr的类选择器&am…

第三届航空航天与控制工程国际学术会议 (ICoACE 2024)

重要信息 会议官网&#xff1a;www.icoace.com 线下召开&#xff1a;2024年11月29日-12月1日 会议地点&#xff1a;陕西西安理工大学金花校区 &#xff08;西安市金花南路5号&#xff09; 大会简介 2024年第三届航空航天与控制工程国际学术会议&#xff08;ICoACE 2024&a…

如何下载链接为blob类型的视频,video 标签 src:blob 链接转下载MP4

文章目录 前言这种链接是如何生成的&#xff1f;原理分析 第一步&#xff0c;找到源地址1.在想下载的视频网页&#xff0c;按f12打开开发人员工具。找到video标签&#xff0c;锁定src属性2.确认src源为blob&#xff1a;样式&#xff0c;转到网络&#xff08;network&#xff09…

Redis | Redis常用命令及示例总结(API)

前言 参考文档&#xff1a;http://doc.redisfans.com/index.html 本篇主要总结Redis的常用命令&#xff0c;笔者在记录命令时的格式如下&#xff1a; 命令关键字&#xff1a;命令示例&#xff1b;命令说明&#xff1b; 命令参数解释及一些说明&#xff1b; 其中命令关键字使用…

【VTK】MFC中使用VTK9.3

MFC中如果使用VTK 碎碎念一、vtk环境配置二、具体实现1、新建类2. 自定义控件3、跑个栗子 总结 碎碎念 如果不是老程序用的MFC&#xff0c;我才不想用MFC去使用VTK呢。 一、vtk环境配置 关于环境配置你可以看这篇文章&#xff0c;在这里不过多赘述。需要注意要选择支持MFC&a…

《译文》2024年11月数维杯国际大学生数学建模挑战赛题目

# 赛题正式发布 2024年第十届数维杯国际大学生数学建模挑战赛顺利开赛&#xff0c;竞赛开始时间为北京时间2024年11月15日09:00至北京时间2024年11月19日09:00&#xff0c;共计4天&#xff0c;竞赛题目正式发布&#xff0c;快来一起围观&#xff0c;你认为今年的哪个题目更具有…

SentenceTransformers×Milvus:如何进行向量相似性搜索

你可曾经历过在 Meetup 上听到一段绝妙的内容&#xff0c;但发现回忆不起具体的细节&#xff1f;作为一名积极组织和参与 Meetup 的开发者关系工程师&#xff0c;我常常会有这种感受。 为了解决这个问题&#xff0c;我开始探索使用相似性搜索技术来筛选大量的非结构化数据。非结…

如何在 Ubuntu 20.04 上的 PyCharm 中使用 Conda 安装并配置 IPython 交互环境

如何在 Ubuntu 20.04 上的 PyCharm 中使用 Conda 安装并配置 IPython 交互环境 要在 Ubuntu 20.04 上的 PyCharm 中配置 IPython 交互环境&#xff0c;并使用 Conda 作为包管理器进行安装&#xff0c;你需要遵循一系列明确的步骤。这些步骤将确保你可以在 PyCharm 中使用 Cond…

VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源

VMware虚拟机(Ubuntu或centOS)共享宿主机网络资源 由于需要在 Linux 环境下进行一些测试工作&#xff0c;于是决定使用 VMware 虚拟化软件来安装 Ubuntu 24.04 .1操作系统。考虑到测试过程中需要访问 Github &#xff0c;要使用Docker拉去镜像等外部网络资源&#xff0c;因此产…

近期两篇NeRF/3DGS-based SLAM方案赏析:TS-SLAM and MBA-SLAM

原文链接&#xff1a;近期两篇NeRF/3DGS-based SLAM方案赏析&#xff1a;TS-SLAM and MBA-SLAM paper1&#xff1a;TS-SLAM: 基于轨迹平滑约束优化的神经辐射场SLAM方法 导读 本文提出了TS-SLAM&#xff0c;一种改进的基于神经辐射场&#xff08;NeRF&#xff09;的SLAM方法…

C# 实现BLE Client 程序与ardunioESP32 通信

编写一个C# Windows 桌面应用程序&#xff0c;与ardunio ESP32 Client 通信。 预备工作 建立一个项目Nuget安装 Microsoft.Windows.SDK.Contracts右击引用菜单中点击&#xff1a;从 packages.config 迁移到 PackageReference using System; using System.Collections.Generi…

【c++丨STL】stack和queue的使用及模拟实现

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C、STL 目录 前言 一、什么是容器适配器 二、stack的使用及模拟实现 1. stack的使用 empty size top push和pop swap 2. stack的模拟实现 三、queue的…

MyBatis-Plus分页插件IPage用法

首先就是service接口需要继承IService<entity> 然后就是业务类实现类中需要继承ServiceImpl<Mapper,entity> Mapper正常写法&#xff0c;继承baseMapepr<entity> IPage的使用方式 QueryWrapper<MdSaleDayPhone> queryWrappernew QueryWrapper<>…

基于阿里云服务器部署静态的website

目录 一&#xff1a;创建服务器实例并connect 二&#xff1a;本地文件和服务器share 三&#xff1a;关于IIS服务器的安装预配置 四&#xff1a;设置安全组 五&#xff1a;建站流程 六&#xff1a;关于备案 一&#xff1a;创建服务器实例并connect 创建好的服务器实例在云…

Android Studio 设置不显示 build-tool 无法下载

2024版本查看build-tool版本 File -> Settings -> Languages & Frameworks -> Android SDK 或者直接打开Settings后搜索“SDK” 解决方案 将 Android Studio 升级到2022.2.1以上的版本将 C:/Windows/System32/drivers/etc/hosts 文件用管理员身份打开&#xff0c…

【JavaSE】【网络编程】UDP数据报套接字编程

目录 一、网络编程简介二、Socket套接字三、TCP/UDP简介3.1 有连接 vs 无连接3.2 可靠传输 vs 不可靠传输3.3 面向字节流 vs 面向数据报3.4 双向工 vs 单行工 四、UDP数据报套接字编程4.1 API介绍4.1.1 DatagramSocket类4.1.1.1 构造方法4.1.1.2 主要方法 4.1.2 DatagramPocket…

MFC图形函数学习10——画颜色填充矩形函数

一、介绍绘制颜色填充矩形函数 前面介绍的几个绘图函数填充颜色都需要专门定义画刷&#xff0c;今天介绍的这个函数可以直接绘制出带有填充色的矩形。 原型1&#xff1a;void FillSolidRect(int x,int y,int cx,int cy,COLORREF color); 参数&#xff1a;&a…