二叉树快速拾遗笔记

2023-05-16

文章目录

    • 前言
    • 二叉树前中后序遍历
    • 反转二叉树
    • 二叉树最大最小深度
    • 对称二叉树
    • 判断是否是平衡二叉树
    • 构造最大二叉树
    • 前序遍历打印二叉树
    • 二叉树层次遍历
    • 二叉树中和为某一值的路径
    • 总结


前言

二叉树基础内容拾遗,使用递归解题三部曲:

  1. 找整个递归的终止条件: 递归应该在什么时候结束?
  2. 找返回值: 应该给上一级返回什么信息?
  3. 本级递归应该做什么:在这一级递归中应该完成什么任务?

提示:以下是本篇文章正文内容,下面案例可供参考

二叉树前中后序遍历

 /**
     * 1. 前序遍历 根 左 右
     * 时间复杂度:O(n),其中 nn 是二叉树的节点数。每一个节点恰好被遍历一次。
     * 空间复杂度:O(n),为递归过程中栈的开销,平均情况下为 O(\log n)O(logn),最坏情况下树呈现链状,为 O(n)O(n)。
     **/
    public void preorderTraversal(TreeNode root) {
        if (root != null) {
            System.out.print(root.val + " "); 
            preorderTraversal(root.left);
            preorderTraversal(root.right);
        }
    }

    /**
     * 中序:左 根 右
     *
     * @param root
     * @return
     */
    public void inorderTraversal(TreeNode root) {
        if (root != null) {
            inorderTraversal(root.left);
            System.out.print(root.val + " ");
            inorderTraversal(root.right);
        }
    }


    /**
     * 后序:左 右 根
     *
     * @param root
     * @return
     */
    public void postorderTraversal(TreeNode root) {
        if (root != null) {
            postorderTraversal(root.left);
            postorderTraversal(root.right);
            System.out.print(root.val + " ");
        }
    }

反转二叉树

  1. 递归实现
public TreeNode invertTree(TreeNode node) {
		if (node == null) {return null;}
		TreeNode temp = node.left;
		node.left = node.right;
		node.right = temp;
		invertTree(node.left);
		invertTree(node.right);
		return node;
	}
  1. 非递归队列实现
public TreeNode invertTree(TreeNode root) {
		if (root == null) {return null;}
		Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(root);
		while (!queue.isEmpty()) {
			TreeNode node = queue.poll();
			TreeNode left = node.left;
			node.left = node.right;
			node.right = left;
			if (node.left != null) {
				queue.offer(node.left);
			}
			if (node.right != null) {
				queue.offer(node.right);
			}
		}
		return root;
	}

二叉树最大最小深度

    /**
     * 最大深度
     */
    public static int treeMaxDepth(TreeNode curr) {
        if (curr != null) {
            int left = treeMaxDepth(curr.left);
            int right = treeMaxDepth(curr.right);
            return left > right ? left + 1 : right + 1;
        }
        return 0;
    }


    /**
     * 最小深度
     */
    public static int treeMinDepth(TreeNode root) {
        TreeNode curr = root;
        if (curr == null) return 0;
        if (curr.left == null && curr.right == null) return 1;

        int min_depth = Integer.MAX_VALUE;
        if (curr.left != null) {
            min_depth = Math.min(treeMinDepth(curr.left), min_depth);
        }
        if (curr.right != null) {
            min_depth = Math.min(treeMinDepth(curr.right), min_depth);
        }
        return min_depth + 1;
    }

对称二叉树


    /**
     * 递归解决
     * <p>
     * 时间复杂度:O(n)O(n),因为我们遍历整个输入树一次,所以总的运行时间为 O(n)O(n),其中 nn 是树中结点的总数。
     * 空间复杂度:递归调用的次数受树的高度限制。在最糟糕情况下,树是线性的,其高度为 O(n)O(n)。因此,在最糟糕的情况下,由栈上的递归调用造成的空间复杂度为 O(n)O(n)。
     *
     * @param root
     * @return
     */
    public boolean isSymmetric(TreeNode root) {
        return isMirror(root, root);
    }

    public boolean isMirror(TreeNode left, TreeNode right) {
        if (left == null && right == null) return true;
        if (left == null || right == null) return false;
        return (left.val == right.val) && isMirror(left.left, right.right) && isMirror(left.right, right.left);
    }

判断是否是平衡二叉树

平衡二叉树即左右两棵子树高度差不大于1的二叉树。

条件:
它的左子树是平衡二叉树,
它的右子树是平衡二叉树,
它的左右子树的高度差不大于1。

在我们眼里,这颗二叉树就3个节点:root、left、right

/**
 * 递归解决,计算子树高度,-1表示子树已经不平衡了
 */
class Solution2 {
    public boolean isBalanced(TreeNode root) {
        return height(root) >= 0;
    }
    private int height(TreeNode root) {
        if (root == null)
            return 0;
        int lh = height(root.left), rh = height(root.right);
        if (lh >= 0 && rh >= 0 && Math.abs(lh - rh) <= 1) {
            return Math.max(lh, rh) + 1;
        } else {
            return -1;
        }
    }

构造最大二叉树

https://leetcode-cn.com/problems/maximum-binary-tree/

给定一个不含重复元素的整数数组 nums 。一个以此数组直接递归构建的 最大二叉树 定义如下:
二叉树的根是数组 nums 中的最大元素。
左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。
右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。
返回有给定数组 nums 构建的 最大二叉树 。

一次递归做了什么?
找当前范围为[l,r]的数组中的最大值作为root节点,然后将数组划分成[l,bond-1]和[bond+1,r]两段,并分别构造成root的左右两棵子最大二叉树

public class _654_最大二叉树 {
    public static void main(String[] args) {
        int[] arr = new int[]{3, 2, 1, 6, 0, 5};
        TreeNode treeNode = new _654_最大二叉树().constructMaximumBinaryTree(arr);
        ArrayList<Integer> list = TreeNode.printFromTopToBottom(treeNode);
        System.out.println(list);

    }
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return maxTree(nums, 0, nums.length - 1);
    }

    public TreeNode maxTree(int[] nums, int l, int r) {
        //1. 判断边界条件 当左边大于右边的时候返回NULL;
        if (l > r) return null;
        //2. 找出最大值索引值
        int maxIndex = findMaxIndex(nums, l, r);
        //3.以最大值新建树顶
        TreeNode root = new TreeNode(nums[maxIndex]);
        //4.分别递归左右子树
        root.left = maxTree(nums, l, maxIndex - 1);
        root.right = maxTree(nums, maxIndex + 1, r);
        //5.返回根节点
        return root;
    }

    public int findMaxIndex(int[] nums, int l, int r) {
        // 初始化最小值和最小index
        int max = Integer.MIN_VALUE, maxIndex = l;
        // 注意这里的遍历的起点和终点的判断条件
        for (int i = l; i <= r; i++) {
            if (max < nums[i]) {
                max = nums[i];
                maxIndex = i;
            }
        }
        return maxIndex;
    }
}

前序遍历打印二叉树

/**
     * 前序打印二叉树 (根->左->右)
     * @param root
     * @return
     */
    public static ArrayList<Integer> printFromTopToBottom(TreeNode root) {
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        if (root==null){
            return arrayList;
        }
        Queue<TreeNode> queue = new LinkedList<TreeNode>();//队列:先入先出
        //将树存入队列中 根、左、右
        queue.offer(root);//添加根:add()和remove()方法在失败的时候会抛出异常(不推荐),offer代替
        while (!queue.isEmpty()){
            TreeNode node= queue.poll();//树当前节点更新;poll()返回第一个元素,并在队列中删除
            arrayList.add(node.val);//保存当前节点
            if (node.left!=null){
                queue.offer(node.left);//左
            }
            if (node.right!=null){
                queue.offer(node.right);//右
            }
        }
        return arrayList;
    }

二叉树层次遍历

示例:
二叉树:[3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7
返回其层序遍历结果:

[
  [3],
  [9,20],
  [15,7]
]
链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal
    /**
     * 时间复杂度:每个点进队出队各一次,故渐进时间复杂度为 O(n)
     * 空间复杂度:队列中元素的个数不超过 n个,故渐进空间复杂度为 O(n)
     * @param root
     * @return
     */
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ret = new ArrayList<>();
        if (root == null) {
            return ret;
        }

        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            List<Integer> list = new ArrayList<>();
            int currentLevelSize = queue.size();
            for (int i = 1; i <= currentLevelSize; ++i) {
                TreeNode node = queue.poll();
                list.add(node.val);
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            ret.add(list);
        }
        return ret;
    }

二叉树中和为某一值的路径

参考:https://www.cnblogs.com/lishanlei/p/10707709.html

由于路径是从根节点出发到叶子节点的,因此我们需要首先遍历根节点,只有前序遍历是首先访问根节点的。
当访问某一个节点时,我们不知道前面经过了哪些节点,所以我们需要将经过的路径上的节点保存下来,每访问一个节点,我们需要把当前节点添加到路径中去。
在遍历下一个节点前,先要回到当前节点的父节点,在去其他节点,当回到父节点时,之前遍历的那个节点已经不在当前路径中了,所以需要删除之前在路径中的那个节点。

在这里插入图片描述

    public List<ArrayList<Integer>> FindPath(TreeNode root, int target) {

        List<ArrayList<Integer>> listAll = new ArrayList<>(); //保存所有符合条件的路径用于返回值
        List<Integer> list = new ArrayList<>(); //存储当前路径
        return SeekPath(listAll, list, root, target);
    }

    private List<ArrayList<Integer>> SeekPath(List<ArrayList<Integer>> listAll, List<Integer> list, TreeNode root, int target) {
        if (root == null) return listAll;
        list.add(root.val);
        target -= root.val;
        if (target == 0 && root.left == null && root.right == null) { //当前路径和是指定值且当前节点是叶子节点
            listAll.add(new ArrayList<>(list));
        }
        SeekPath(listAll, list, root.left, target);
        SeekPath(listAll, list, root.right, target);
        list.remove(list.size() - 1);  //递归回到父节点时需要在路径中删除上一个节点信息
        return listAll;
    }
    //  FindPath(tree, 22) output: [[10, 5, 7], [10, 12]]

总结

未完待续

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

二叉树快速拾遗笔记 的相关文章

  • aptitude和apt-get的区别和联系【转,有添加和修改】

    起初GNU Linux系统中只有 tar gz 用户 必须自己编译他们想使用的每一个程序 在Debian出现之後 xff0c 人们认为有必要在系统 中添加一种机 制用来管理 安装在计算机上的软件包 人们将这套系统称为dpkg 至此着名的 p
  • Mac终端配置代理

    export http proxy 61 socks5 127 0 0 1 49719 配置http访问 export https proxy 61 socks5 127 0 0 1 49719 配置https export all pro
  • 如何将Java程序打成可执行jar包

    前几天 xff0c 公司运维找我让我帮他写个Java小程序 xff0c 读取磁盘指定目录的文件 xff0c 然后根据读取的内容查询第三方接口 xff0c 再将第三方接口响应的数据写入磁盘文件 然后我花了半天给他写了这个小程序 xff0c 但
  • javafx_scenebuilder-2_0-windows.msi 百度云盘下载

    javafx scene builder 官网下载很慢 网上有很多人分享 xff0c 都要付积分下载 下面是从官网下载好的 xff0c 传我百度网盘了 xff0c 有需要的大家去下载吧 链接 xff1a https pan baidu co
  • 100+套Axure数据可视化大屏展示原型模板及通用主键库

    内置多种实用美观的可视化组件库及行业模板库 xff0c 行业模板涵盖 xff1a 金融 教育 医疗 政府 交通 制造等多个行业 xff0c 提供设计参考 随着大数据的发展 xff0c 可视化大屏在各行各业得到越来越广泛的应用 可视化大屏不再
  • 数据可视化大屏UI界面

    数据可视化大屏 科技大屏展示 智慧城市 智慧农业 领导页展示大屏 PSD文件 UI可视化大屏模板PSD文件 156套可视化大屏PSD设计文件 xff0c 送给有需要的人 格式格式 xff1a PSD jpg 适合人群 xff1a 可视化大屏
  • SpringBoot 自定义注解实现Redis缓存功能

    背景 最近小A的公司要做一个大屏可视化平台 xff0c 主要是给领导看的 xff0c 领导说这个项目要给领导演示 xff0c 效果好不好直接关系到能不能拿下这个项目 xff0c 领导还补了一句 这项目至少是百万级的 xff0c 大伙要全力以
  • Linux 下 chmod 777 修改权限

    一 rwxrwxrwx 777 Unix Linux 的操作系统 xff0c 每个文件 文件夹也被看作是文件 都按读 写 运行设定权限 例如用ls l命令列文件表时 xff0c 得到如下输出 xff1a rw r r 1 mchopin u
  • Spring创建对象初始化bean的时机分为两种形式:

    import org junit Test import org springframework context ApplicationContext import org springframework context support C
  • 页面动态数据的滚动效果——jquery滚动组件(vticker.js)

    lt script language 61 34 javascript 34 src 61 34 lirms Test jquery 1 4 2 js 34 gt lt script gt lt script language 61 34
  • MySQL 查询结果以百分比显示

    找了一些资料 xff0c 然后我是用到了MySQL字符串处理中的两个函数concat 和left 1 span style color ff0000 CONCAT span str1 str2 返回来自于参数连结的字符串 如果任何参数是 N
  • rpm包安装过程中依赖问题“libc.so.6 is needed by XXX”解决方法

    转自 xff1a http raksmart idcspy com 781 rpm包安装过程中依赖问题 libc so 6 is needed by XXX 解决方法 与本教程高度相关文章 xff08 读完应该可以解决你的问题 xff09
  • 艺博: linux命令大宝典系列之mkdir创建目录

    在成长的过程中 人总要经历一些痛苦和挫折才能更加成熟与坚强 目录 mkdir是什么mkdir的语法mkdir的选项含义mkdir的实例1 使用mkdir命令创建一个dir1目录 默认权限775 2 使用mkdir m命令新建一个dir2目录
  • linux命令xrandr修改桌面分辨率

    xrandr临时修改分辨率 方法一 打开终端xrandr Screen 0 minimum 8 x 8 current 1366 x 768 maximum 32767 x 32767 eDP1 connected primary 1366
  • Python 教你训练一个98%准确率的微博抑郁文本分类模型(含数据)

    Paddle是一个比较高级的深度学习开发框架 xff0c 其内置了许多方便的计算单元可供使用 xff0c 我们之前写过PaddleHub相关的文章 xff1a 1 Python 识别文本情感就这么简单 2 比PS还好用 xff01 Pyth
  • 记一次神奇的时间转换问题(SheetJS)

    最近在写一个功能 xff0c 使用SheetJS读取Excel表格 xff0c 在读取日期的时候发现了一个隐藏很深的坑 xff0c 特此记录一下 SheetJS读取Excel文件时 xff0c 可指定参数 cellDates true xf
  • 通信常识

    bsc指的是基站控制器 xff08 Base Station Controller xff09 由一下模块组成 xff1a AM CM模块 xff1a 话路交换和信息交换的中心 BM模块 xff1a 完成呼叫处理 信令处理 无线资源管理 无
  • python解析基于xml格式的日志文件

    大家中午好 xff0c 由于过年一直还没回到状态 xff0c 好久没分享一波小知识了 xff0c 今天 xff0c 继续给大家分享一波python解析日志的小脚本 首先 xff0c 同样的先看看日志是个啥样 都是xml格式的 xff0c 是
  • 如何在无显示屏的情况下调试树莓派

    一 准备 1 树莓派 xff1b 2 SD卡 读卡器 网线 xff1b 3 系统镜像下载链接 xff1b 4 软件 xff1a SD Card Formatter下载链接 xff1b balenaEtcher下载链接 xff1b VNC V

随机推荐

  • VNC怎么和宿主机共享粘贴板

    VNC怎么和宿主机共享粘贴板 假设目标主机是linux xff0c 终端主机是windows xff08 就是在windows上使用VNC登陆linux xff09 在linux中执行vncconfig nowin amp 在linux选中
  • 系统调用,进程切换

    模式切换 不等同于 进程上下文切换 当进程调用系统调用或者发生中断时 xff0c CPU从用户模式 xff08 用户态 xff09 切换成内核模式 xff08 内核态 xff09 xff0c 此时 xff0c 无论是系统调用程序还是中断服务
  • brew换源

    bin zsh c 34 curl fsSL https gitee com cunkai HomebrewCN raw master Homebrew sh 34 mac安装homebrew失败怎么办 xff1f 金牛肖马的回答 知乎 h
  • 2022年书单

    2022年书单 纸质书 类别序号书名进度社会科学0 从零开始的女性主义 x1f44c 社会科学1 如何抑制女性写作 x1f44c 社会科学2 父权制与资本主义 社会科学3 下流社会 x1f44c 社会科学4 低欲望社会 x1f44c 社会科
  • 书店漫游记录

    目录 北京 上海 杭州 天津 南京 青岛 深圳 香港 北京 万圣书园 豆瓣书店 野草书店 三联韬奋书店 xff08 三里屯 xff09 三联韬奋书店 xff08 美术馆 xff09 Pageone xff08 北京坊 xff09 Pageo
  • C++ std::string 不可初始化为NULL及基本用法

    偶然看到一个问题 xff0c 顺便总结一下std string C 43 43 basic string S construct null not valid stackoverflow例子 std string 字符串不可以初始化为NUL
  • 通过查看端口状态查看mongodb是否已经启动

    LINUX环境下 xff0c 可以通过查看端口27017的状态查看mongod是否已经启动 netstat lanp span class hljs string grep 34 span span class hljs number 27
  • linux & windows C++开发差异

    新手注意事项 1 文件与目录的大小写以及路径分隔符的差别 windows下不区分大小写 xff0c 路径分隔符一般使用 xff1b linux下区分大小写 xff0c 路径分隔符使用 2 itoa 函数在linux下并不存在 所以使用类似s
  • 深度学习结合SLAM的研究思路/成果整理之(一)使用深度学习方法替换SLAM中的模块

    整理了部分近两年深度学习结合SLAM的一些研究成果 xff08 参考知乎帖子https www zhihu com question 66006923 和泡泡机器人公众号 xff0c 附上论文链接和已找到的源代码 数据集链接 xff0c 大
  • 深度学习与自动驾驶领域的数据集(KITTI,Oxford,Cityscape,Comma.ai,BDDV,TORCS,Udacity,GTA,CARLA,Carcraft)

    http blog csdn net solomon1558 article details 70173223 Torontocity HCI middlebury caltech 行人检测数据集 ISPRS航拍数据集 mot challe
  • 又一遍……ORB_SLAM2+ZED相机(SDK2.2.1)+CUDA9.0+ROS Kinetic 安装测试 some tips

    很久没碰过ORB SLAM2了 xff0c 今天有需要 xff0c 再来试一遍 xff5e ORB SLAM2的github链接 1 安装ORB SLAM2的依赖库 按照链接一步一步来就可以 eigen直接用命令安装就可以 sudo apt
  • MacOS设置终端代理

    前言 国内的开发者或多或少都会因为网络而烦恼 xff0c 因为一些特殊原因有时候网络不好的时候需要使用代理才能完成对应的操作 原来我一直都是使用斐讯路由器然后刷了梅林的固件 xff0c 直接在路由器层面设置转发代理 xff0c 把一些国内网
  • Linux SIGPIPE信号产生原因与解决方法

    TCP 四次握手 产生SIGPIPE的原因 SIGPIPE信号产生的原因 xff1a 简单来说 xff0c 就是客户端程序向服务器端程序发送了消息 xff0c 然后关闭客户端 xff0c 服务器端返回消息的时候就会收到内核给的SIGPIPE
  • Homebrew最新安装--解决安装超时的问题

    更新 2021 1 20 可以直接用下边的脚本进行安装 bin zsh c span class token string 34 span class token variable span class token variable spa
  • TIDB使用时的注意点笔记

    场景 xff1a 虽然TiDB号称完全兼容MySQL 5 7 协议 MySQL 5 7 常用的功能及语法 xff0c 但是其与MySQL数据库仍然存在一些差异 xff0c 可能会导致下游TiDB环境故障 以下是我们使用TiDB时需要重点关注
  • SpringBoot结合MyBatis-Plus快速CRUD笔记

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 DTO amp DO二 示例1 定义Controller2 定义Service和实现3 定义Mapper4 前端访问测试
  • Java最佳实践笔记

    一 常量定义最佳实践 span class token keyword public span span class token keyword final span span class token keyword class span
  • 聊聊JavaSPI

    文章目录 前言一 SPI 示例二 SPI原理与双亲委派机制1 MySQL Driver2 DataX 插件的热插拔也是破坏双亲委派的一种3 Tomcat类加载同样是破坏了双亲委托 总结参考文章 前言 SPI 全称为 Service Prov
  • 实时平台开发笔记

    文章目录 一 背景二 功能模块划分1 作业台主要功能任务生命周期 2 任务列表主要功能 3 项目管理4 模板管理5 UDF管理 三 问题解决1 kerberos认证问题2 分布式锁解决Job名称冲突问题3 自定义线程池用以监控线程运行情况4
  • 二叉树快速拾遗笔记

    文章目录 前言二叉树前中后序遍历反转二叉树二叉树最大最小深度对称二叉树判断是否是平衡二叉树构造最大二叉树前序遍历打印二叉树二叉树层次遍历二叉树中和为某一值的路径总结 前言 二叉树基础内容拾遗 xff0c 使用递归解题三部曲 xff1a 找整