带你清晰理解二叉树的递归与解题思路(框架思维!)

news2024/11/23 3:14:33

文章目录

  • 前言:
    • 🐕啥叫“框架思维”
    • 🏨深入理解前中后序
    • 🪀前序位置与后序位置区别
  • 两种解题思路:
    • 下面用几道简单题来练习一下:
    • 🎀力扣 104.二叉树的最大深度
    • 🎀力扣 144.翻转二叉树

前言:

本篇博客会带你理解面对二叉树题型时的两种解题思维模式:(我先总结出来,不理解往下看)
1、是否可以通过遍历一遍二叉树得到答案?
如果可以,用一个 traverse 函数配合外部变量来实现,这叫「遍历」的思维模式。(就是根据当前节点的值来进行处理操作,可以得出答案)

2、是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?
如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值,这叫「分解问题」的思维模式。(就是将问题分解为左右子树的问题,看看是否通过对左右子树进行处理可以得出答案)

但是无论使用哪种思维模式,你都需要思考
如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做? 其他的节点不用你操心,递归函数会帮你在所有节点上执行相同的操作。

🐕啥叫“框架思维”

先解释一下啥叫“框架思维”,就是看到一道算法题,你下意识的就想到用什么方法,甚至还没有仔细看题目限制条件,就可以基本将70%的代码写出来,剩下没写的就是限制条件。
(举个例子:就是英语考试的作文题,如果你有一套写作框架/模板(就是你背的英语作文模板),就能很快的完成一篇英语作文)

🏨深入理解前中后序

我们学习二叉树时,都学过前序遍历、中序遍历、后序遍历,先来回顾一下,找一下区别吧

在这里插入图片描述在这里插入图片描述在这里插入图片描述

是不是分别在前序位置、中序位置、后序位置上呢?那么它们的位置不同,产生的作用也不同
如果你意识到了这一点,证明你已经理解了它们作用不一样。

🪀前序位置与后序位置区别

你也注意到了,只要是递归形式的遍历(数组也能递归),都可以有前序位置和后序位置,分别在递归之前和递归之后.
所谓前序位置,就是刚进入一个节点(元素)的时候,后序位置就是即将离开一个节点(元素)的时候,那么进一步,你把代码写在不同位置,代码执行的时机也不同:
在这里插入图片描述

🎀下面以一个链表入手,让你理解前序位置与后序位置的区别,而二叉树无非是多了一个中序位置而已。

思考:如何倒序打印链表呢?如何正序打印链表呢

在这里插入图片描述
在这里插入图片描述

看到这里,你是否对这张图中内容理解了呢在这里插入图片描述
那么说回二叉树也是一样的,只不过多了一个中序位置罢了。
教科书里只会问你前中后序遍历结果分别是什么,所以对于一个只上过大学数据结构课程的人来说,他大概以为二叉树的前中后序只不过对应三种顺序不同的 List<Integer> 列表。
但是我想说,前中后序是遍历二叉树过程中处理每一个节点的三个特殊时间点,绝不仅仅是三个顺序不同的 List:

前序位置的代码在刚刚进入一个二叉树节点的时候执行;

后序位置的代码在将要离开一个二叉树节点的时候执行;

中序位置的代码在一个二叉树节点左子树都遍历完,即将开始遍历右子树的时候执行。

你注意本文的用词,我一直说前中后序「位置」,就是要和大家常说的前中后序「遍历」有所区别
你可以在前序位置写代码往一个 List 里面塞元素,那最后得到的就是前序遍历结果;但并不是说你就不可以写更复杂的代码做更复杂的事。
画成图,前中后序三个位置在二叉树上是这样:

在这里插入图片描述
你可以发现每个节点都有「唯一」属于自己的前中后序位置,所以其他的节点不用你操心,递归函数会帮你在所有节点上执行相同的操作。

两种解题思路:

二叉树题目的递归解法可以分两类思路,(无论题目是简单困难)

  • 第一类是遍历一遍二叉树得出答案,
  • 第二类是通过分解成左右子树问题计算出答案

下面用几道简单题来练习一下:

力扣 104.二叉树的最大深度

🎀力扣 104.二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。在这里插入图片描述
提示:

  • 树中节点的数量在 [0, 104] 区间内
    -100 <= Node.val <= 100

🏅解法一能否利用分解为左右子树来推出结果

  public int maxDepth(TreeNode root) {
  //思路:能否利用遍历一次二叉树解决问题?可以,【前序位置,当前进入时++,后序位置,回溯退出时--】
        //思路:能否利用分解为左右子树来推出结果?可以,【后序位置】
        //思路2:
        if(root==null){
            return 0;
        }
        int leftDepth = maxDepth(root.left);//获取左子树的最大深度
        int rightDepth = maxDepth(root.right);//获取右子树的最大深度
        return Math.max(leftDepth,rightDepth)+1;
    }

🏅解法二能否利用遍历一次二叉树解决问题

 public int maxDepth(TreeNode root) {
        //思路:能否利用遍历一次二叉树解决问题?可以,【前序位置,当前进入时++,后序位置,回溯退出时--】
        //思路:能否利用分解为左右子树来推出结果?可以,【后序位置】
        //思路1:
        if(root==null){
            return 0;
        }
        maxDepth++;//进入当前节点
        maxDepth(root.left);//进入左子树
        res=Math.max(res,maxDepth);
        maxDepth(root.right);//进入右子树
        maxDepth--;//从右子树回溯到当前节点,深度-1
        return res;
    }

力扣 144.翻转二叉树

🎀力扣 144.翻转二叉树

给定一棵二叉树的根节点 root,请左右翻转这棵二叉树,并返回其根节点。
在这里插入图片描述

提示:

  • 树中节点的数量在 [0, 100] 区间内
    -100 <= Node.val <= 100

🏅解法一能否利用分解为左右子树来推出结果

 public TreeNode mirrorTree(TreeNode root) {
        //思路:是否能通过分解左右子树来解决问题
        
        if(root==null){
            return root;
        }
        TreeNode left= mirrorTree(root.left);
        TreeNode right= mirrorTree(root.right);
        //后序位置
        root.left=right;
        root.right=left;
        return root;
    }

🏅解法二能否利用遍历一次二叉树解决问题

public TreeNode mirrorTree(TreeNode root) {
        //思路:是否能通过一次二叉树遍历推出结果呢?可以
        if(root==null){
            return root;
        }
        //前序位置
        TreeNode temp=root.left;//先寄存当前节点的左子树
        root.left=root.right;
        root.right=temp;
        mirrorTree(root.left);
        mirrorTree(root.right);
        return root;
    }

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

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

相关文章

树莓派部署.net core控制台程序

1、在自己的电脑上使用VS写一个Net6.0的控制台程序&#xff0c;我假设我就写个Helloworld。 发布项目 使用mobaxterm上传程序 就传三个文件就行 回到在mobaxterm中&#xff0c;进入目录输入&#xff1a;cd consolepublish,运行程序&#xff1a; dotnet ConsoleApp1.dll 输出h…

亚马逊精细化运营是什么意思?旺季如何高效进行数据精细化运营?—站斧浏览器

亚马逊精细化运营是什么意思&#xff1f; 精细化运营是去精心打造一件产品&#xff0c;例如把店铺运作的某款产品挑出来着重分析。分析方式可以是把卖家所看中在亚马逊中排名较好的产品&#xff0c;用EXCEL电子表格对选中的产品&#xff0c;在平台相关数据表现做数据统计对比。…

unity ugui text 超链接和下划线,支持富文本

项目需要用到该功能&#xff0c; 搜索和参考了很多文章&#xff0c;要么不支持富文本&#xff0c;要不没有下划线&#xff0c;要么是错误的&#xff0c;修修改改后满足我的需求&#xff0c;代码如下 using System; using System.Collections.Generic; using System.Text; usin…

微信小程序备案流程操作详解,值得收藏

目录 一、小程序备案法律法规参考 二、备案前准备 2.1 备案入口 2.1.1、未上架小程序 2.1.2、已上架小程序 (二)备案类型 (三)备案材料准备 3.1、小程序备案材料 3.2、前置审批材料 3.3、个人备案 3.4、非个人备案 三、备案整体流程 (一)备案信息填写 1、主体信息…

两种方式获取Stream流的方式

java.util.stream.Stream<T> 是Java 8 新加入的最常用的流接口。&#xff08;这并不是一个函数式接口&#xff09;获取一个流有以下两种方式 所有的 Collection集合 都可以通过stream默认方法获取流 Stream接口 的静态方法of可以获取数组对应的流 package com.csdn.s…

想要精通算法和SQL的成长之路 - 分割数组的最大值

想要精通算法和SQL的成长之路 - 分割数组的最大值 前言一. 分割数组的最大值1.1 二分法 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 分割数组的最大值 原题链接 首先面对这个题目&#xff0c;我们可以捕获几个关键词&#xff1a; 非负整数。非空连续子数组。 那么我…

选实验室超声波清洗机易忽视的内容?小型清洗机的优点有?

实验室超声波清洗机如今在行业内占据着重要的一席之地&#xff0c;摒弃了传统模式&#xff0c;坚持以超声波为主的清洗方式&#xff0c;在市场中获得的反响强烈。服务好&#xff0c;有诚信的实验室超声波清洗机能够消除客户的后顾之忧&#xff0c;工作人员会以真诚态度向客户提…

机器人制作开源方案 | 棘轮小车

1. 运动功能说明 棘轮小车&#xff08;Ratchet Car&#xff09;是一种基于棘轮原理设计的小型车辆&#xff0c;它结合了棘轮机制和移动装置&#xff0c;用于特定的应用场景&#xff0c;这种设计使得小车能够实现单向移动或防止逆向移动。棘轮小车的主要特点包括&#xff1a; …

【藏经阁一起读】(72)__《Hologres 一站式实时数仓客户案例集》

【藏经阁一起读】&#xff08;72&#xff09; __《Hologres 一站式实时数仓客户案例集》 目录 【藏经阁一起读】&#xff08;72&#xff09; 一、实时数仓概念 二、Hologres 三、Hologres 一站式实时数仓客户案例集 3.1、电商 3.1.1、实时数仓 Hologres 首次走进阿里淘特…

BUUCTF jarvisoj_level0 1

目录 一、分析二、EXP三、本地打不通&#xff1f;远程能打通&#xff1f; 一、分析 查看文件信息 关键信息 64位程序栈不可执行 IDA64反汇编 进入第一个函数 栈溢出 shift F12查找字符串 点进去 发现是一个后门函数 二、EXP from pwn import *context.arch amd64 #…

Godot 单元测试

前言 单元测试是我们常用的功能&#xff0c;Godot作为一个游戏&#xff0c;单元测试和热重载是我们常用的功能。这里我们讲解最简单的单元测试的情况。 Godot 配置 我们添加一个最简单的节点&#xff0c;挂载一个最简单的脚本。 添加测试方法&#xff08;只能是静态方法&…

Flex 词法分析实验实现(电子科技大学编译技术Icoding实验)

Flex 词法分析 此为电子科技大学编译技术 实验1&#xff1a;词法分析 将具体实现中的三个文件和自己的实验报告一起上传才能通过 根据词法分析实验中给定的文法&#xff0c;利用 flex 设计一词法分析器&#xff0c;该分析器从标准输入读入源代码后&#xff0c;输出单词的类别编…

Linux线程同步实例

线程同步实例 1. 生产消费者模型基本概念2. 基于BlockingQueue的生产者消费者模型3. 基于环形队列的生产消费模型4. 线程池 1. 生产消费者模型基本概念 生产者消费者模型是一种常用的并发设计模式&#xff0c;它可以解决生产者和消费者之间的速度不匹配、解耦、异步等问题。生…

Vue 绑定style和class

在应用界面中&#xff0c;某些元素的样式是动态的。class 与 style 绑定就是专门用来实现动态样式效果的技术。 如果需要动态绑定 class 或 style 样式&#xff0c;可以使用 v-bind 绑定。 绑定 class 样式【字符串写法】 适用于&#xff1a;类名不确定&#xff0c;需要动态指…

Stm32_标准库_8_ADC_光敏热敏传感器_测数值

在测量光敏传感器数值得基础上手动将通道改成热敏传感器通道即可 由于温度传感器的测量范围是-20 ~ 105摄氏度&#xff0c;所以输出温度得考虑带上符号这就需要在原有输出光照强度代码的基础上新添加几个函数 函数1&#xff1a; uint16_t AD_Getvailue(uint8_t ADC_Channel){…

六、DHCP实验

拓扑图&#xff1a; DHCP协议&#xff0c;给定一个ip范围使其自动给终端分配IP&#xff0c;提高了IP分配的效率 首先对PC设备选择DHCP分配ip 首先先对路由器的下端配置网关的ip 创建地址池&#xff0c;通过globle的方式实现DHCP ip pool 地址池名称 之后设置地址池的网关地址…

最大数【贪心3】

题目 分析 代码 class Solution { public:string largestNumber(vector<int>& nums) {vector<string> str;for(auto & x : nums){str.push_back(to_string(x));}sort(str.begin(),str.end(),[](const string& s1,const string& s2){return s1 s…

【JavaEE】_servlet程序的编写方法

目录 1. 创建项目 2. 引入依赖 3. 创建目录结构 3.1 在main目录下创建一个webapp目录 3.2 在webapp目录下创建一个WEB-INF目录 3.3 在WEB-INF目录下创建一个web.xml文件 3.4 在web.xml中进行代码编写 4. 编写代码 4.1 在java目录下创建类 4.2 打印"hello world&…

亚马逊测评安全吗?

测评可以说是卖家非常宝贵的财富&#xff0c;通过测评和广告相结合&#xff0c;可以快速有效的提升店铺的产品销量&#xff0c;提高转化&#xff0c;提升listing权重&#xff0c;但现在很多卖家找真人测评补单后店铺出现问题导致大家对测评的安全性感到担忧&#xff0c;因为真人…

基于php+thinphp+vue的商品购物商城网站

运行环境 开发语言&#xff1a;PHP 数据库:MYSQL数据库 使用框架:ThinkPHPvue 开发工具:VScode/Dreamweaver/PhpStorm等均可 项目简介 基于tpvue的商品定制交易网站实现前台与后台&#xff0c;用户前台&#xff1b;首页、商品信息、我的收藏、留言板、个人中心、后台管理、管…