左神算法基础巩固--3

news2025/3/3 5:22:09

文章目录

  • 二叉树
    • 二叉树的遍历
      • 先序遍历
      • 中序遍历
      • 后序遍历
    • 解答
      • 二叉树的宽度优先遍历
    • 在这里插入图片描述 一颗完全二叉树具有以下特征:1.不存在任何一个节点具有右子树但不存在左子树.2.不存在任何一个节点在满足1的情况下左右子树不全且其后续节点不为叶子节点 根据以上特征我们便可以解决上述问题代码如下: leaf就是是否遇到了左右子树不双全的情况。 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/52cc9f58cf304c6eb4f87e43a4e24f2f.png)
    • 在这里插入图片描述


二叉树

二叉树的遍历

二叉树的遍历依靠的是递归序,即每一个节点一共可以回到自己三次,也因此根据这个可以得到二叉树的先序遍历,中序遍历,后序遍历

先序遍历

先序遍历(Preorder Traversal)是二叉树遍历的一种方式,其遍历顺序为:
1.访问根节点。
2.先序遍历左子树。
3.先序遍历右子树。
在先序遍历中,根节点是第一个被访问的节点。这种遍历方式常用于创建树的副本或复制树的结构,因为它首先访问根节点,然后再依次访问子节点。
其按递归序来理解便是当第一次来到当前节点时便打印

递归实现先序遍历代码:

import java.util.ArrayList;
import java.util.List;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class PreorderTraversal {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        preorderHelper(root, result);
        return result;
    }

    private void preorderHelper(TreeNode node, List<Integer> result) {
        if (node == null) {
            return;
        }
        // 1第一次来到这个函数
        result.add(node.val);
        preorderHelper(node.left, result);
        // 2 第2次来到
        preorderHelper(node.right, result);
        //3 第3次来到
    }
}

非递归实现先序遍历,非递归实现先序遍历的话可以使用栈来实现,我们需要先吧头节点加入栈中再将右子节点压入栈中和左子节点压入栈中,java代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class PreorderTraversal {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }

        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);

        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val); // 访问当前节点

            // 先压入右子节点,再压入左子节点,以保证左子节点先被访问
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }

        return result;
    }
}

中序遍历

中序遍历(Inorder Traversal)是二叉树遍历的一种方式,其遍历顺序为:
中序遍历左子树.
访问根节点.
中序遍历右子树.
在中序遍历中,对于二叉搜索树(BST),遍历的结果会按照节点值的升序排列.这种遍历方式常用于获取二叉搜索树的有序序列.
其按递归序来理解便是当第二次来到当前节点时便打印

递归实现中序遍历代码:

import java.util.ArrayList;
import java.util.List;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class InorderTraversal {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        inorderHelper(root, result);
        return result;
    }

    private void inorderHelper(TreeNode node, List<Integer> result) {
        if (node == null) {
            return;
        }
        inorderHelper(node.left, result);
        result.add(node.val);
        inorderHelper(node.right, result);
    }
}

非递归实现中序遍历,我们一直向左遍历将遍历到的节点压入栈中直到左子树为空,再弹出栈顶,并开始右子树的遍历,java代码:在这里插入图片描述

后序遍历

后序遍历(Postorder Traversal)是二叉树遍历的一种方式,其遍历顺序为:
后序遍历左子树.
后序遍历右子树.
访问根节点.
在后序遍历中,根节点是最后一个被访问的节点.这种遍历方式常用于删除树的节点或计算树的某些属性时,因为先处理子节点可以确保在处理根节点时,子节点已经被处理完毕
其按递归序来理解便是当第三次来到当前节点时便打印

递归实现后序遍历代码:

import java.util.ArrayList;
import java.util.List;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class PostorderTraversal {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        postorderHelper(root, result);
        return result;
    }

    private void postorderHelper(TreeNode node, List<Integer> result) {
        if (node == null) {
            return;
        }
        postorderHelper(node.left, result);
        postorderHelper(node.right, result);
        result.add(node.val);
    }
}

非递归实现后序遍历,我们先创建处两个栈,在第一个栈中我们先压入头节点,之后循环将第一个栈中的当前节点压入到第二个栈中,同时先压入当前节点的左节点,再压入当前节点的右节点,之后再遍历输出第二个栈中的内容便是后序遍历,java代码:
在这里插入图片描述

解答

在这里插入图片描述

二叉树的宽度优先遍历

在二叉树的宽度优先遍历中我们采用队列的方式实现,我们先将头节点加入队列,并将队列中的节点弹出,同时将弹出节点的左右节点压入队列,后不断循环直到队列为空。
在这里插入图片描述
将上述代码进行修改便能得到上述问题的解,我们只需要加入一个当前的层数的变量和一个当前的层数有多少节点的变量便能够解决
在这里插入图片描述
我们先创建一个HashMap用来存储每个节点在哪一层,同时在进行宽度优先遍历的时候,每遍历到一个节点就判断他与当前的层数是否相等相等便更新当前的层数的节点数,如果不相等便将树的最大节点数与当前层数的节点数相比较如果大于树的层的最大节点数便更新树的层的最大节点数。
在这里插入图片描述
面对这种题我们可以使用中序遍历解决,我们直接中序遍历这棵树,并将其所有节点都加入到一个数组中,遍历这个数组判断其是否为升序数组,如果是返回true,如果不是返回false
我们也可以使用另一种方式解答这道题: 我们首先需要明确的是判断一棵树是否为二叉搜索树是由其左子树和右子树以及当前节点决定的,当一棵树的左子树不为二叉搜索树或其右子树不为二叉搜索树或当前节点小于或等于其前一个节点,均能认为这棵树不为二叉搜索树。因此我们可以用递归的方法解决这个问题,我们先用递归的方法判断其左子树是否为二叉搜索树,如果不是便直接返回该树不是二叉搜索树,如果是再进行判断当前当前节点死否小于或等于其前一个节点,如果是便返回该数不是二叉搜索树,如果不是便更新前一个节点的值,再对右子树进行判断。
在这里插入图片描述


在这里插入图片描述
一颗完全二叉树具有以下特征:1.不存在任何一个节点具有右子树但不存在左子树.2.不存在任何一个节点在满足1的情况下左右子树不全且其后续节点不为叶子节点
根据以上特征我们便可以解决上述问题代码如下:
leaf就是是否遇到了左右子树不双全的情况。
在这里插入图片描述

在这里插入图片描述
判断一棵树是否为满二叉树可以运用二叉树树形dp问题的套路解决,即向他的左右子树要信息,以此题为例,判断一个二叉树是否为满二叉树,我们需要知道这棵树的高度和这棵树的节点个数,即我们需要向每个节点的父节点返回以自己为头节点的子树有多少个节点,以及以自己为头节点的子树的高度是什么,这些信息可以封装起来方便返回。

故这道题的解题思路为,我们先得到当前节点的左子树的信息和右子树的信息,然后,我们根据这些信息得到我们需要返回的以当前节点为头节点的子树的高度,之后我们再根据左右子树的信息得到以当前节点为头节点的子树的节点树,最后拼接成自己需要返回的信息返回。

这道题的解题代码为:
在这里插入图片描述


在这里插入图片描述
判断一棵树是否是平衡二叉树可以运用二叉树树形dp问题的套路解决,即向他的左右子树要信息,以此题为例,判断一棵二叉树是否是平衡二叉树,我们需要知道其左子树的是否为平衡二叉树,其右子树是否为平衡二叉树,以及其左子树的高度和其右子树的高度。即我们需要向每个节点的父节点返回以自己为头节点的子树是否平衡,以自己为头节点的子树的深度,这些信息可以封装起来方便返回。

故这道题的解题思路为,我们先得到当前节点的左子树的信息和右子树的信息,然后,我们根据这些信息得到我们需要返回的以当前节点为头节点的子树的高度,之后我们再根据左右子树的信息得到当前节点是否平衡(根据左子树是否平衡,右子树是否平衡,左右子树的高度差是否小于2),最后拼接成自己需要返回的信息返回。

这道题的解题代码为:
在这里插入图片描述


在这里插入图片描述
这道题与上面的几道题虽然都需要运用递归的方法进行求解但却有些不同,在求解该题时,我们需要先需要找到每个节点的父节点,并存储起来,之后再找到node1的父节点和各个祖先节点并存储。之后再让node2在node1的父节点和各个祖先节点找到相同的最低公共祖先节点

这道题的解题代码如下:
在这里插入图片描述
在这里插入图片描述
我们也可以采用更为简单的方法,即从头查找,寻找以当前节点为头的子树是否存在node1或node2如果是则说明当前节点是node1或node2的祖宗节点
在这里插入图片描述


在这里插入图片描述

在解这道题中,我们可以直接中序遍历这棵树并将其存储到一个数组中,之后遍历这个数组得到node节点的后继节点
当然我们也可以使用另一种更加省时省力的方法解决
解题思路:当node节点有右子树的时候,其后继节点即为其右子树的最左节点,当node节点没有右子树的时候node节点的后继节点为以x为左树的父节点

在这里插入图片描述


在这里插入图片描述
我们可以用_表示节点的值到此为止,用#表示null,则先序序列化便显而易见了,我们只需要在先序遍历的基础了添加上述约定的字符
在这里插入图片描述

在这里插入图片描述
反序列化则是依据先序遍历和上述约定画出一棵树
在这里插入图片描述


在这里插入图片描述
解该问题时我们需要总结出一个规律那就是每次折叠都是在原来的基础上往上添加down往下添加up 有这个规律后,我们直接遍历生成便能解决问题
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

高山旅游景区有效降低成本,无人机山下到山上物资吊运技术详解

在高山旅游景区&#xff0c;传统的物资运输方式往往面临人力成本高昂、效率低下等问题&#xff0c;而无人机技术的引入为这一难题提供了新的解决方案。以下是对无人机从山下到山上进行物资吊运技术的详细解析&#xff1a; 一、无人机物资吊运技术的优势 1. 降低人力成本&#…

APP上架之Android 证书 MD5 指纹

Android 证书 MD5 指纹 1. 什么是 Android 证书 MD5 指纹&#xff1f; Android 证书 MD5 指纹是对证书数据进行 MD5 哈希运算后得到的 128 位字符串。在 Android 开发中&#xff0c;每个证书在理论上都有一个唯一的 MD5 指纹&#xff0c;用于识别和验证证书的有效性。证书指纹…

用户界面的UML建模11

然而&#xff0c;在用户界面方面&#xff0c;重要的是要了解《boundary》类是如何与这个异常分层结构进行关联的。 《exception》类的对象可以作为《control》类的对象。因此&#xff0c;《exception》类能够聚合《boundary》类。 参见图12&#xff0c;《exception》Database…

网络安全-XSS跨站脚本攻击(基础篇)

漏洞扫描的原理 1.跨站脚本攻击介绍 xss跨站脚本攻击&#xff1a; xSS 全称&#xff08;Cross site Scripting &#xff09;跨站脚本攻击&#xff0c;是最常见的Web应用程序安全漏洞之一&#xff0c;位于OWASP top 10 2013/2017年度分别为第三名和第七名&#xff0c;XSS是指攻…

CODESYS MODBUS TCP通信(禾川Q1 PLC作为MODBUS TCP从站)

禾川Q1 PLC MODBUS TCP 通信(PLC作为MODBUS TCP通信主站) 禾川Q1 PLC MODBUS TCP通信(CODESYS平台完整配置+代码)-CSDN博客文章浏览阅读28次。MATLAB和S7-1200PLC水箱液位高度PID控制联合仿真(MODBUSTCP通信)_将matlab仿真导入plc-CSDN博客文章浏览阅读722次。本文详细介绍了如…

golang OpcUaClient

实现功能 package mainimport ("fmt""log""opcuaclient/util/plugin/client/opcclient""os""os/signal""syscall" )func main() {OPCUATest()// 监听操作系统信号&#xff0c;阻塞直到接收到信号quit : make(chan…

git commit冲突,需输入提交信息合并提交

git commit时冲突&#xff0c;需输入提交信息合并提交&#xff0c;该如何操作&#xff1f; windows按esc键进入命令模式&#xff0c;输入&#xff1a;wq并按enter保存并退出即可。

Linux/Ubuntu/银河麒麟 arm64 飞腾FT2000 下使用 arm64版本 linuxdeployqt 打包Qt程序

文章目录 一、前言二、环境三、准备1、下载Linuxdeployqt源码2、下载Appimagetool-aarch64.AppImage四、编译linuxdeployqt1.配置环境变量2.编译linuxdeployqt五、安装patchelf六、配置Appimagetool七、打包Qt程序重要提示:测试启动应用八、其他九、最后一、前言 因为项目需要…

操作系统大题整理

专题一 程序代码题&#xff1a;程序设计与分析&#xff0c;主要考的是线程&#xff0c;多线程的并发&#xff1f; 大题第一问&#xff08;1&#xff09;操作系统的结构有哪几种常用的结构&#xff1f; 宏内核&#xff1a;宏内核是将操作系统的主要功能模块都集中在内核的一种结…

SQL编程语言

第一章 1. 数据库是长期储存在计算机内&#xff0c;由专门的数据管理软件(数据库管理系统)&#xff0c;进行统一组织和管理控制的大量数据的集合。 2.数据库的基本特点不包括可以快速检索。 3. 数据管理技术的发展经历了&#xff1a;人工管理阶段、文件系统阶段、数据库系统阶…

【跨域问题】

跨域问题 官方概念&#xff1a; 当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域本质来说&#xff0c;是前端请求给到后端时候&#xff0c;请求头里面&#xff0c;有一个 Origin &#xff0c;会带上 协议域名端口号等&#xff1b;后端接受到请求&…

Linux(CentOS7)安装JDK和Maven

文章目录 CentOS软件安装方式JDK安装Maven安装 CentOS软件安装方式 安装方式特点二进制发布包安装软件已经针对具体平台编译打包发布&#xff0c;只要解压&#xff0c;修改配置即可。例如tomcatrpm(redhat package manager)安装软件已经按照redhat的包管理规范进行打包&#x…

RabbitMQ 可观测性最佳实践

RabbitMQ 简介 RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写&#xff0c;支持多种客户端。它通过使用交换机&#xff08;Exchanges&#xff09;、队列&#xff08;Queues&#xff09;和绑定&#xff08;Bindings&#xff09;来路由消息&#xff…

Github Copilot学习笔记

&#xff08;一&#xff09;Prompt Engineering 利用AI工具生成prompt设计好的prompt结构使用MarkDown语法&#xff0c;按Role, Skills, Constrains, Background, Requirements和Demo这几个维度描述需求。然后收输入提示词&#xff1a;作为 [Role], 拥有 [Skills], 严格遵守 […

单片机-定时器中断

1、相关知识 振荡周期1/12us; //振荡周期又称 S周期或时钟周期&#xff08;晶振周期或外加振荡周期&#xff09;。 状态周期1/6us; 机器周期1us; 指令周期1~4us; ①51单片机有两组定时器/计数器&#xff0c;因为既可以定时&#xff0c;又可以计数&#xff0c;故称之为定时器…

高比例压缩:Linux 中的压缩命令与技巧

文章目录 高比例压缩&#xff1a;Linux 中的压缩命令与技巧1. 压缩格式的选择2. gzip 命令示例&#xff1a;压缩文件示例&#xff1a;解压文件 3. bzip2 命令示例&#xff1a;压缩文件示例&#xff1a;解压文件 4. xz 命令示例&#xff1a;压缩文件示例&#xff1a;解压文件 5.…

【ArcGIS Pro二次开发实例教程】(1):图层的前置、后置

一、简介 此工具要实现的功能是&#xff1a;将内容框中当前选定的图层移到最顶层或最底层。 主要技术要点包括&#xff1a; 1、Config.daml文件设置&#xff08;UI设置&#xff09; 2、按钮的图片和位置设置 3、当前选定图层的获取 4、图层在内容列表中位置的获取和移动 …

Sprint Boot教程之五十:Spring Boot JpaRepository 示例

Spring Boot JpaRepository 示例 Spring Boot建立在 Spring 之上&#xff0c;包含 Spring 的所有功能。由于其快速的生产就绪环境&#xff0c;使开发人员能够直接专注于逻辑&#xff0c;而不必费力配置和设置&#xff0c;因此如今它正成为开发人员的最爱。Spring Boot 是一个基…

ESP32 IDF VScode出现头文件“无法打开 源 文件 ”,并有红色下划线警告

问题背景&#xff1a; ESP32 IDF VScode出现头文件“无法打开 源 文件 ”&#xff0c;并有红色下划线警告&#xff1a; 解决办法&#xff1a; 在工程里面的.vscode文件夹下&#xff0c;检查是否存在c_cpp_properties.json文件&#xff0c;如果没有可以手动创建添加。如图…

【Shell脚本】Docker构建Java项目,并自动停止原镜像容器,发布新版本

本文简述 经常使用docker部署SpringBoot 项目&#xff0c;因为自己的服务器小且项目简单&#xff0c;因此没有使用自动化部署。每次将jar包传到服务器后&#xff0c;需要手动构建&#xff0c;然后停止原有容器&#xff0c;并使用新的镜像启动&#xff0c;介于AI时代越来越懒的…