「二叉树进阶题解:构建、遍历与结构转化全解析」

在这里插入图片描述

文章目录

  • 根据二叉树创建字符串
    • 思路
    • 代码
  • 二叉树的层序遍历
    • 思路
    • 代码
  • 二叉树的最近公共祖先
    • 思路
    • 代码
  • 二叉搜索树与双向链表
    • 思路
    • 代码
  • 从前序与中序遍历序列构造二叉树
    • 思路
    • 代码
  • 总结

根据二叉树创建字符串

题目:
在这里插入图片描述
样例:
在这里插入图片描述
在这里插入图片描述
可以看见,唯一特殊的就是左子树,当右子树存在的时候左子树不存在的时候,我们需要用()代表空,但是没有左子树,又没有右子树的时候,我们不需要做任何处理。

思路

结合题目和样例,我们可以知道,特殊的是右子树存在但是左子树不存在的情况,这种情况,可以归类为root->left||root->right。这种情况,我们就要处理左子树。首先我们应该处理一下需要返回的字符串,
在这里插入图片描述

  1. 有左子树的情况,当有左子树的时候,我们直接递归左子树,并将结果加上()
  2. 没有左子树,但是有有右子树,也需要递归一次左子树,因为需要加上空的()
  3. 有右子树,直接递归右子树,最后在结果上加上()。

代码

class Solution {
public:
    string tree2str(TreeNode* root) {
        if(root==nullptr) return  "";
        string result=to_string(root->val);

        if(root->left||root->right)
        {
            result+="("+tree2str(root->left)+")";
        }
        if(root->right)
        {
            result+="("+tree2str(root->right)+")";
        }
        return result;
    }
};

二叉树的层序遍历

题目:
在这里插入图片描述
样例:
在这里插入图片描述

思路

这道题可以直接借助队列,借助队列的时候我们还需要一个levelsize来记录每层的个数即可

代码

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(root==nullptr)return vector<vector<int>>();
        //创建队列
        queue<TreeNode*> q;
        q.push(root);
        vector<vector<int>> result;
        int levelsize=1;
        while(!q.empty())
        {
            vector<int> level;
            for(int i=0;i<levelsize;i++)
            {
                auto front=q.front();
                q.pop();
                if(front->left)q.push(front->left);
                if(front->right)q.push(front->right);
                level.push_back(front->val);
            }
            result.push_back(level);
            levelsize=q.size();
        }
        return result;
    }
};

二叉树的最近公共祖先

题目:
在这里插入图片描述
样例:
在这里插入图片描述

思路

需要找公共祖先,首先我们肯定要找到这两个节点的位置,然后这两个节点向上返回,我们用left表示是向左子树搜索这个节点,用right表示向右子树搜索这两个节点,如果能找到就返回对应的节点,p或者q,如果没找到就返回nullptr,如果left和right都不为空说明p和q分布在左子树和右子树,并且root就是两个的最近的祖先,如果其中一个是nullptr说明,p和q分布在一边,直接返回不为空的那个就是最近公共祖先。

代码

class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        //找对应的节点
        if(root==nullptr||root==p||root==q)return root;
        //记录左子树的结果
        TreeNode* left=lowestCommonAncestor(root->left,p,q);
        //记录右子树的结果
        TreeNode* right=lowestCommonAncestor(root->right,p,q);
        //如果左右子树都不为空则说明和q分布在左子树和右子树
        if(left&&right)return root;
        //如果其中一个是空,则说明p是祖先或者q是祖先
        return (left==nullptr)?right:left;
    }
};

二叉搜索树与双向链表

题目:
在这里插入图片描述
样例:
在这里插入图片描述

思路

首先我们来看看子问题:
这肯定是一个中序遍历吧,因为只有中序遍历才能是顺序的,这很明显,接下来就是我们需要处理的中序中间的部分,就是节点之间关系的转变。
在这里插入图片描述

从这里可以知道左指针是指向前驱的指针,右指针是指向后继的指针。
在这里插入图片描述
这里我们分别对左子树和右子树进行中序遍历,第一个遍历到4,因为4是第一个,所以前驱应该是nullptr,因为每次我们都需要前驱,所以这里我们用parent表示前驱,parent就应该被初始化为nullptr,当中序遍历到达4的时候4是不需要处理的因为4的左子树和右子树都是nullptr,唯一需要处理的就是4的前驱应该是nullptr,处理完之后,我们需要返回前驱,因为6需要指向前驱,前驱不为空的情况下还需要将前驱的右指针指向后继,4的后继是6,所以我们只需要进行两个步骤,第一个步骤是处理前驱,前驱是已知节点指向前驱节点,所以我们不用担心是否为空,因为我们的前驱parent初始化是nullptr,所以在parent指向后继的时候,需要判断一下parent是否是空。
最后再改变前驱即可左子树的前驱就是最后一个访问的节点,左中右,所以上图应该是8。

代码

class Solution {
public:
	TreeNode* parent=nullptr;
	void InOrder(TreeNode* root)
	{
		//root是nullptr返回
		if(!root)return;
		//中序遍历
		InOrder(root->left);

		//先将root的前驱指针指向parent,root赋值给parent
		root->left = parent;
		if(parent) parent->right=root;
		parent = root;
		InOrder(root->right);
	}
	//左指针指向前面,右指针指向后面
    TreeNode* Convert(TreeNode* pRootOfTree) {
		if(pRootOfTree==nullptr)return nullptr;
		TreeNode* first=pRootOfTree;
		while(first->left) first=first->left;
		InOrder(pRootOfTree);
		return first;
    }
};

从前序与中序遍历序列构造二叉树

题目:
在这里插入图片描述
样例:
在这里插入图片描述

思路

首先已知两个序列:
在这里插入图片描述
前序和中序,根据前序的特性我们可以知道,第一个元素肯定是根节点,所以这里我们可以根据前序遍历找到根节点,然后在中序遍历中找到根节点的位置。
在这里插入图片描述
找到在中序中的位置之后我们可以通过中序的特性,左边是左子树,右边是右子树,来对左区间和右区间递归,根节点的left指向左区间,根节点的right指向右区间,然后循环这个过程。

代码

class Solution {
public:
    //构建二叉树
    TreeNode* Build(vector<int>& preorder,int preL,int preR,vector<int> inorder,int inL,int inR)
    {
        //当左边大于右边的时候返回nullptr
        if(preL>preR)return nullptr;
        //找出根节点的值
        int rootval=preorder[preL];
        TreeNode *root=new TreeNode(rootval);

        //找到在中序遍历中的位置
        int index=inL;
        while(inorder[index]!=rootval) index++;

        //计算左子树在前序中的位置
        int leftSize=index-inL;

        root->left=Build(preorder,preL+1,preL+leftSize,inorder,inL,index-1);
        root->right=Build(preorder,preL+leftSize+1,preR,inorder,index+1,inR);
        return root;
    }
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return Build(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
    }
};

总结

通过多道二叉树题目的练习,我们全面了解了二叉树的各种操作和特性。每道题目都涉及不同的场景和技巧,如节点删除、树的遍历、以及特殊结构转换等,不仅加深了对二叉树结构的理解,也提升了编写递归和迭代算法的能力。这些经验为进一步深入数据结构和算法的学习打下了扎实的基础。希望这篇总结能够帮助你在二叉树题目中更得心应手,为更复杂的数据结构问题做好准备。

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

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

相关文章

SCI被「On Hold」意味着什么?会有哪些影响?

本文首发于“生态学者”微信公众号&#xff01; 继Chemosphere在2023年7月被「On Hold」之后&#xff0c;昨晚Science of The Total Environment 被标记为「On Hold」状态在各大公众号和朋友圈被刷屏&#xff01;&#xff08;官方网址&#xff1a;https://mjl.clarivate.com/s…

PouchDB - 免费开源的 JavaScript 数据库,轻量易用,用于离线保存数据的场景

这个 JS 工具库可以让我们很容易地实现数据缓存到本地的需求&#xff0c;要写的代码量也很少。 PouchDB 是一个基于 JavaScript 语言开发的轻量级的数据库&#xff0c;可以在浏览器、Node.js 等环境中使用。作者是一位来自国外的女开发工程师 Alba Herreras。 这是一个运行在浏…

el-datepicker禁用未来日期(包含时分秒)type=‘datetime’

文章目录 实现代码方式1&#xff1a;当选中日期的时候去更新一次。方式2: 优化版本&#xff0c;使用 setTimout 每分钟更新一次。&#xff08;防止选中日期之后过了很久再去选择时分秒时没有根据当前时间去改变&#xff09; el-datepicker 选择器禁用未来日期&#xff0c;动态禁…

重生之“我打数据结构,真的假的?”--2.单链表(无习题)

C语言中的单链表总结 单链表是一种基础的数据结构&#xff0c;广泛应用于C语言编程中。它由节点组成&#xff0c;每个节点包含数据和指向下一个节点的指针。单链表的优点在于动态内存分配和高效的插入与删除操作。本文将详细探讨单链表的定义、基本操作、应用场景以及相关示例…

Gateway 统一网关

一、初识 Gateway 1. 为什么需要网关 我们所有的服务可以让任何请求访问&#xff0c;但有些业务不是对外公开的&#xff0c;这就需要用网关来统一替我们筛选请求&#xff0c;它就像是房间的一道门&#xff0c;想进入房间就必须经过门。而请求想要访问微服务&#xff0c;就必须…

ComfyUI系列——新手安装ComfyUI,就是这么简单

比较Midjoury、WebUI和ComfyUI 在了解ComfyUI的时候&#xff0c;还有其它两款类似的产品&#xff0c;于是就搜集了一下资料&#xff0c;以下是Midjoury、WebUI&#xff08;通常指的是Stable Diffusion Web UI&#xff09;和ComfyUI三者之间的异同点对比表。 特性MidjourneySt…

国内短剧系统源码搭建系统平台小程序新玩法

在数字化内容消费日益普及的今天&#xff0c;短剧小程序作为一种新兴的内容平台&#xff0c;其功能设计至关重要。一个好的短句系统不仅需要提供优质的内容展示&#xff0c;还需要具备一系列优秀功能以满足用户和运营者的需求。以下是一些必备的功能特点&#xff1a; 为大家介…

WebGL 添加背景图

1. 纹理坐标&#xff08;st坐标&#xff09;简介 ST纹理坐标&#xff08;也称为UV坐标&#xff09;是一种二维坐标系统&#xff0c;用于在三维模型的表面上精确地定位二维纹理图像。这种坐标系统通常将纹理的左下角映射到(0,0)&#xff0c;而右上角映射到(1,1)。 S坐标&#x…

leetcode_128:最长连续序列

给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1&#xff1a; 输入&#xff1a;nums [100,4,200,1,3,2] 输出&#xff1a;4 解…

CSS揭秘:7. 伪随机背景

前置知识&#xff1a;CSS 渐变&#xff0c;5. 条纹背景&#xff0c;6. 复杂的背景图案 前言 本篇主要内容依然是关于背景的&#xff0c;无限平铺的背景会显得整齐美观&#xff0c;但又有些呆板&#xff0c;如何实现背景的多样性和随机性&#xff0c;是本篇的核心。 一、四种颜…

AI周报(10.20-10.26)

AI应用-牙科AI产品Pearl Pearl是一家致力于改善牙科患者护理的人工智能驱动型公司&#xff0c;推出了首款获得美国食品药品监督管理局&#xff08;FDA&#xff09;批准的人工智能&#xff0c;能够读取牙科X光片并即时识别疾病。今年7月获得5800万美元的B轮融资&#xff0c;以加…

GESP一级真题分析-202303-选择题1-输入输出设备、存储单位、默认数据类型、标识符命名

PDF文档回复:20241026 1 相关知识点 1) 输入输出设备 输入设备 是外界向计算机传送信息的装置。在微型计算机系统中&#xff0c;最常用的输入设备是键盘和鼠标。 此外还有电子光笔、数字化仪、图形扫描仪、触摸屏、麦克风、视频输入设备、条形码扫描等 输出设备 作用是将计…

Java-图书管理系统

我的个人主页 欢迎来到我的Java图书管理系统&#xff0c;接下来让我们一同探索如何书写图书管理系统吧&#xff01; 1管理端和用户端 2建立相关的三个包&#xff08;book、operation、user&#xff09; 3建立程序入口Main类 4程序运行 1.首先图书馆管理系统分为管理员端和…

6.stm32 OLED显示屏

调试方式 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息 显示屏调试&#xff1a;直接将显示屏连接到单片机&#xff0c;将调试信息打印在显示屏上 Keil调试模式&#xff1a;借助Keil软件的调试模式&#…

【阅读笔记】Instruction-based Hypergraph Pretraining

Abstract中可以提炼的信息&#xff1a; 背景&#xff1a;预训练的作用是为了增强图学习模型将知识从大数据集转移到下游任务的适应性。 想解决的问题&#xff1a;训练目标的不同与数据分布的不同会阻碍预训练知识的迁移。 文章受到基于指令的提示词在语言模型训练广泛应用的启发…

Vue学习笔记(四)

事件处理 我们可以使用 v-on 指令 (通常缩写为 符号) 来监听 DOM 事件&#xff0c;并在触发事件时执行一些 JavaScript。用法为 v-on:click"methodName" 或使用快捷方式 click"methodName" 事件处理器的值可以是&#xff1a; 内联事件处理器&#xff1…

鹅厂面试官:Transformer 为何需要位置编码?

最近这一两周看到不少互联网公司都已经开始秋招发放Offer。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球…

前端零基础入门到上班:【Day2】开发环境VSCode安装

VSCode 安装教程&#xff1a;图文保姆教程 引言 在前端开发中&#xff0c;选择合适的代码编辑器是提高工作效率的重要一步。Visual Studio Code&#xff08;简称 VSCode&#xff09;作为一款强大的开源编辑器&#xff0c;因其简洁易用、功能强大、扩展性好而广受开发者喜爱。…

【智能大数据分析 | 实验四】Spark实验:Spark Streaming

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈智能大数据分析 ⌋ ⌋ ⌋ 智能大数据分析是指利用先进的技术和算法对大规模数据进行深入分析和挖掘&#xff0c;以提取有价值的信息和洞察。它结合了大数据技术、人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&a…

Postman常见问题及解决方(全)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、网络连接问题 如果Postman无法发送请求或接收响应&#xff0c;可以尝试以下操作&#xff1a; 检查网络连接是否正常&#xff0c;包括检查网络设置、代理设置…