瑞_力扣LeetCode_二叉树相关题

文章目录

    • 说明
    • 题目 144. 二叉树的前序遍历
      • 题解
    • 题目 94. 二叉树的中序遍历
      • 题解
    • 题目 145. 二叉树的后序遍历
      • 题解
    • 题目 105. 从前序与中序遍历序列构造二叉树
      • 题解
    • 题目 106. 从中序与后序遍历序列构造二叉树
      • 题解

🙊 前言:本文章为瑞_系列专栏之《刷题》的力扣LeetCode系列,主要以力扣LeetCode网的题进行解析与分享。本文仅供大家交流、学习及研究使用,禁止用于商业用途,违者必究!

在这里插入图片描述

说明

  本文主要是配合《瑞_数据结构与算法_二叉树》对二叉树的知识进行提升和拓展

题目 144. 二叉树的前序遍历

  原题链接:Leetcode144. 二叉树的前序遍历

  给你二叉树的根节点 root ,返回它节点值的前序遍历。

  示例 1:

在这里插入图片描述

输入:root = [1,null,2,3]
输出:[1,2,3]

  示例 2:

输入:root = []
输出:[]

  示例 3:

输入:root = [1]
输出:[1]

  示例 4:

在这里插入图片描述

输入:root = [1,2]
输出:[1,2]

  示例 5:

在这里插入图片描述

输入:root = [1,null,2]
输出:[1,2]

  提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

  进阶:递归算法很简单,你可以通过迭代算法完成吗?

题解

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
		/*
         * 栈
         */
        LinkedList<TreeNode> stack = new LinkedList<>();

        /*
         * 代表当前节点
         */
        TreeNode current = root;
        /*
         * 最近一次弹栈的元素
         */
        TreeNode pop = null;

        List<Integer> result = new ArrayList<>();
        while (!stack.isEmpty() || current != null) {
            if (current != null) {
                stack.push(current);
                // 待处理左子树
                result.add(current.val);
                current = current.left;
            } else {
                TreeNode peek = stack.peek();
                // 没有右子树
                if (peek.right == null) {
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                }
                // 右子树处理完成
                else if (peek.right == pop) {
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                }
                // 待处理右子树
                else {
                    current = peek.right;
                }
            }
        }
        return result;
    }
}

题目 94. 二叉树的中序遍历

  原题链接:Leetcode94. 二叉树的中序遍历

  给定一个二叉树的根节点 root ,返回 它的中序遍历 。

  示例 1:

在这里插入图片描述

输入:root = [1,null,2,3]
输出:[1,3,2]

  示例 2:

输入:root = []
输出:[]

  示例 3:

输入:root = [1]
输出:[1]

  提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

  进阶: 递归算法很简单,你可以通过迭代算法完成吗?

题解

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        /*
         * 栈
         */
        LinkedList<TreeNode> stack = new LinkedList<>();

        /*
         * 代表当前节点
         */
        TreeNode current = root;
        /*
         * 最近一次弹栈的元素
         */
        TreeNode pop = null;

        List<Integer> result = new ArrayList<>();
        while (!stack.isEmpty() || current != null) {
            if (current != null) {
                stack.push(current);
                // 待处理左子树
                current = current.left;
            } else {
                TreeNode peek = stack.peek();
                // 没有右子树
                if (peek.right == null) {
                    result.add(peek.val);
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                }
                // 右子树处理完成
                else if (peek.right == pop) {
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                }
                // 待处理右子树
                else {
                    result.add(peek.val);
                    current = peek.right;
                }
            }
        }
        return result;
    }
}

题目 145. 二叉树的后序遍历

  原题链接:Leetcode145. 二叉树的后序遍历

  示例 1:
在这里插入图片描述

输入:root = [1,null,2,3]
输出:[3,2,1]

  示例 2:

输入:root = []
输出:[]

  示例 3:

输入:root = [1]
输出:[1]

  说明:

  • 树中节点的数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100

  进阶:递归算法很简单,你可以通过迭代算法完成吗?

题解

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        /*
         * 栈
         */
        LinkedList<TreeNode> stack = new LinkedList<>();
        /*
         * 代表当前节点
         */
        TreeNode current = root;
        /*
         * 最近一次弹栈的元素
         */
        TreeNode pop = null;

        List<Integer> result = new ArrayList<>();
        while (!stack.isEmpty() || current != null) {
            if (current != null) {
                stack.push(current);
                // 待处理左子树
                current = current.left;
            } else {
                TreeNode peek = stack.peek();
                // 没有右子树
                if (peek.right == null) {
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                    result.add(pop.val);
                }
                // 右子树处理完成
                else if (peek.right == pop) {
                    // 获取最近一次弹栈的元素
                    pop = stack.pop();
                    result.add(pop.val);
                }
                // 待处理右子树
                else {
                    current = peek.right;
                }
            }
        }
        return result;
    }
}

题目 105. 从前序与中序遍历序列构造二叉树

  原题链接:Leetcode105. 从前序与中序遍历序列构造二叉树

  给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

  示例 1:

在这里插入图片描述

	输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
	输出: [3,9,20,null,null,15,7]

  示例 2:

	输入: preorder = [-1], inorder = [-1]
	输出: [-1]

  提示:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorderinorder无重复 元素
  • inorder 均出现在 preorder
  • preorder 保证 为二叉树的前序遍历序列
  • inorder 保证 为二叉树的中序遍历序列

题解

  思路

	1. 前序遍历(preorder)的第一个值肯定是根节点。通过preorder寻找根节点。
	2. 中序遍历(inorder)在根节点之前的值是根节点的左子树部分,而之后的值是根节点的右子树部分。通过inorder区分左右子树部分。
	3. 通过循环inorder使用根节点确定中序遍历的左右子树部分、前序遍历的左右子树部分。
	4. 根据1.2.3.继续分为子问题,递归解决。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] preOrder, int[] inOrder) {
        if (preOrder.length == 0) {
            return null;
        }
        // 创建根节点
        int rootValue = preOrder[0];
        TreeNode root = new TreeNode(rootValue);
        // 区分左右子树
        for (int i = 0; i < inOrder.length; i++) {
            if (inOrder[i] == rootValue) {
                // 0 ~ i-1 左子树
                // i+1 ~ inOrder.length -1 右子树
                int[] inLeft = Arrays.copyOfRange(inOrder, 0, i); 
                int[] inRight = Arrays.copyOfRange(inOrder, i + 1, inOrder.length); 

                int[] preLeft = Arrays.copyOfRange(preOrder, 1, i + 1);
                int[] preRight = Arrays.copyOfRange(preOrder, i + 1, preOrder.length); 

                root.left = buildTree(preLeft, inLeft); 
                root.right = buildTree(preRight, inRight); 
                break;
            }
        }
        return root;
    }
}

瑞:可以使用HashMap优化,以及新数组可以通过索引坐标参数传递优化。具体可见本系列HashMap章节(后续更新)

题目 106. 从中序与后序遍历序列构造二叉树

  原题链接:Leetcode106. 从中序与后序遍历序列构造二叉树

  给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

  示例1:

在这里插入图片描述

	输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
	输出:[3,9,20,null,null,15,7]

  示例2:

	输入:inorder = [-1], postorder = [-1]
	输出:[-1]

  提示:

  • 1 <= inorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i], postorder[i] <= 3000
  • inorderpostorder 都由 不同 的值组成
  • postorder 中每一个值都在 inorder
  • inorder 保证是树的中序遍历
  • postorder 保证是树的后序遍历

题解

  思路

	1. 后序遍历(postorder)的最后一个元素就是根节点。通过postorder寻找根节点。
	2. 中序遍历(inorder)在根节点之前的值是根节点的左子树部分,而之后的值是根节点的右子树部分。通过inorder区分左右子树部分。
	3. 通过循环inorder使用根节点确定中序遍历的左右子树部分、后序遍历的左右子树部分。
	4. 根据1.2.3.继续分为子问题,递归解决。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] inOrder, int[] postOrder) {
        if (inOrder.length == 0) {
            return null;
        }
        // 根
        int rootValue = postOrder[postOrder.length - 1];
        TreeNode root = new TreeNode(rootValue);
        // 切分左右子树
        for (int i = 0; i < inOrder.length; i++) {
            if (inOrder[i] == rootValue) {
                int[] inLeft = Arrays.copyOfRange(inOrder, 0, i);
                int[] inRight = Arrays.copyOfRange(inOrder, i + 1, inOrder.length);

                int[] postLeft = Arrays.copyOfRange(postOrder, 0, i);
                int[] postRight = Arrays.copyOfRange(postOrder, i, postOrder.length - 1);

                root.left = buildTree(inLeft, postLeft);
                root.right = buildTree(inRight, postRight);
                break;
            }
        }
        return root;
    }
}



本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


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

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

相关文章

基于微信小程序的学生公寓宿舍电费管理系统的研究与实现

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

c++多态(1) -- 子类型及什么是多态

目录 代码分析: 代码中我们使用了三种方式: 为什么子类对象可以赋值给父类对象? 子类型的传递性: 使用父类的指针指向子类的对象: 总结: 子类型和多态的联系及什么是多态 那父类指针指向子类对象的用处在哪? 子类型: 从名字看就知道和继承有关。 子类型…

Windows 版Oracle 数据库(安装)详细过程

首先到官网上去下载oracle64位的安装程序 第一步&#xff1a;将两个datebase文件夹解压到同一目录中。 当下载完成后,它里面是两个文件夹 win64_11gR2_database_1of2, win64_11gR2_database_2of2,我们需要把其中的一个database文件夹整合在一起(复制一个database文件夹到另一…

2024.02.07

总结C类中的继承&#xff0c;虚继承&#xff0c;多态等概念&#xff08;画思维导图&#xff09;

政安晨:机器学习快速入门(四){pandas与scikit-learn} {随机森林}

咱们将在这篇文章中使用更复杂的机器学习算法。 随机森林 基本定义 随机森林(Random Forest)是一种机器学习算法&#xff0c;属于集成学习(ensemble learning)的一种。它是通过构建多个决策树&#xff08;即森林&#xff09;来进行预测和分类的。 随机森林的主要特点是采用了…

如何配置Pycharm服务器并结合内网穿透工具实现远程开发

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;…

Idea Git Review插件

idea git plugin 添加了一些常用的小插件 可以右键打开git bash窗口 可以右键选中文字点击baidu fanyi 可以通过搜索git用户名 指定开始时间查询某个版本自己提交的所有代码文件 可以通过点击蓝色行数&#xff0c;跳转到指定的改动代码块 资源地址&#xff1a; git-pl…

【C语言 - 力扣 - 反转链表】

反转链表题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 题解1-迭代 假设链表为 1→2→3→∅&#xff0c;我们想要把它改成 ∅←1←2←3。 在遍历链表时&#xff0c;将当前节点的 next 指针改为指向前一个节点。由于节点没…

STM32 新建寄存器版本MDK工程简要步骤

新建工程文件夹 新建一个工程根目录文件夹&#xff0c;并在该文件夹里新建D/M/O/P/U文件夹。 Drivers&#xff1a;存放与硬件相关的驱动层文件Middlewares&#xff1a;存放正点原子提供的中间层组件文件和第三方中间层文件Output&#xff1a;存放工程编译输出文件Projects&am…

前端学习笔记 | HTML5+CSS3静态网页制作的技巧(持续更新)

注&#xff1a;本文的css样式均使用less写法 1、字体居中 &#xff08;1&#xff09;先text-align:center;行内元素水平居中 &#xff08;2&#xff09;再line-heigh:(盒子高度);行内元素垂直居中 text-align: center;line-height: ( 30 / vw ); 2、盒子居中 情景1&#…

【AIGC风格prompt深度指南】掌握绘画风格关键词,实现艺术模仿的革新实践

[小提琴家]ASCII风格&#xff0c;点&#xff0c;爆炸&#xff0c;光&#xff0c;射线&#xff0c;计算机代码 由冰和水制成的和平标志]非常详细&#xff0c;寒冷&#xff0c;冰冻&#xff0c;大气&#xff0c;照片逼真&#xff0c;流动&#xff0c;16K 胡迪尼模拟火和水&#x…

MySQL数据引擎、建库及账号管理

目录 一、MySQL数据库引擎 1.1.MySQL常见数据库引擎 1.InnoDB(MySQL默认引擎) 2.MyISAM 3.MEMORY&#xff08;Heap&#xff09; 1.2.存储引擎查看 二、建库 1.默认数据库介绍 2.建库 3.查看数据库 4.删除数据库 三、账号管理 1.创建用户 1.创建用户并设置登陆密码…

Ryzen Controller 最新版本下载

Ryzen Controller 最新版本下载 GitLab中最新版本地址&#xff1a; Releases Ryzen Controller Team / Ryzen Controller GitLab 然后语言切换成简体中文&#xff0c;就可以愉快使用啦

Springboot多种方法处理静态资源:设置并访问静态资源目录

&#xff5e;目录嗷&#xff5e; 静态文件application设置方法 配置详解编写配置优缺点 设置配置类方法 配置详解编写配置优缺点 总结 作者&#xff1a;Mintimate 博客&#xff1a;https://www.mintimate.cn Mintimate’s Blog&#xff0c;只为与你分享 静态文件 静态资源&…

FlinkSql 窗口函数

Windowing TVF 以前用的是Grouped Window Functions&#xff08;分组窗口函数&#xff09;&#xff0c;但是分组窗口函数只支持窗口聚合 现在FlinkSql统一都是用的是Windowing TVFs&#xff08;窗口表值函数&#xff09;&#xff0c;Windowing TVFs更符合 SQL 标准且更加强大…

uniapp 本地存储的方式

1. uniapp 本地存储的方式 在uniapp开发中&#xff0c;本地存储是一个常见的需求。本地存储可以帮助我们在客户端保存和管理数据&#xff0c;以便在应用程序中进行持久化存储。本文将介绍uniapp中本地存储的几种方式&#xff0c;以及相关的代码示例。 1.1. 介绍 在移动应用开发…

浅谈bypass Etw

文章目录 c#ExecuteAssemblybypass etw c# loader 一种是通过反射找到指定空间的类中method进行Invoke 另一种是通过EntryPoint.Invoke加载 反射加载 Assembly.Load()是从String或AssemblyName类型加载程序集&#xff0c;可以读取字符串形式的程序集 Assembly.LoadFrom()从指定…

elk之倒排索引

写在前面 本文看下es的倒排索引相关内容。 1&#xff1a;正排索引和倒排索引 正排索引就是通过文档id找文档内容&#xff0c;而倒排索引就是通过文档内容找文档id&#xff0c;如下图&#xff1a; 2&#xff1a;倒排索引原理 假定我们有如下的数据&#xff1a; 为了建立倒…

第21讲:动态内存管理

1.为什么要有动态内存分配 2.malloc和free 3.calloc 4.realloc 5.笔试题 6.总结c/c中程序内存区域划分 1.为什么要有动态内存分配 为了调整申请的空间大小&#xff0c;使程序员可以申请和释放空间&#xff0c;提高程序的灵活性 2.malloc和free 作用&#xff1a;分配一块…

安装Pytorch中的torchtext之CUDA版的正确方式

安装Pytorch和torchtext&#xff1a; Previous PyTorch Versions | PyTorch Installing previous versions of PyTorchhttps://pytorch.org/get-started/previous-versions/ 上面的命令如下&#xff1a; pip install torch2.1.2 torchvision0.16.2 torchaudio2.1.2 --index-…