IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode重建二叉树详解 -> 正文阅读

[数据结构与算法]LeetCode重建二叉树详解

题目描述

在这里插入图片描述

原理分析

(1)大致思路

下面讲解一下,前序遍历+中序遍历如何确定一个唯一的二叉树。关于二叉树的基本知识,请看二叉树的基本操作及联系。对此就不再过多重复。对于前序遍历顺序:根、左子树、右子树;对于中序的遍历顺序:左子树、根、右子树。所以通过前序遍历,我们获取前序第一个结点就是这个树的根,再在中序遍历中找到该结点的位置。在中序中,根的左边全部的是属于根左子树的结点,根的右边全是属于根的右子树的结点。
详细如图:
在这里插入图片描述做完第一步之后,我们会发现,我们目前只具体确定了哪一个是根节点,哪些结点分别属于左右子树。但是由于树的递归特性。属于左子树的结点仍然符合前序遍历,中序遍历特点的。所以我们就是需要对刚刚分离出来的两部分分别再次用上述的方法,确定根节点,确定哪些结点属于左子树,哪些结点属于右子树。一次类推,直到结束。这就是这道题的大致思路。

(2)细节阐述

这道题还是有不少值得思考的地方。
1、我们如何表示哪些结点是属于左子树,右子树?
答:前序、中序的给出都vector,所以我们可以通过下标确定范围来做到。前序:【根,左子树,右子树】。中序:【左子树,根,右子树】。他们都是三种类别结点都是集中在一起,很好区分。
2、递归的结束条件是什么?
答:这个还是要结合具体代码分析,目前可以确定的是,当我们控制范围时,如果出现范围不合法(不存在)的情况就说明已经没有左子树或者右子树了,就要返回。

代码实现

注:一般在我的题解中,范围控制,代码这样书写的原因都会通过注释的方式写在对应代码旁边,帮助读者理解分析代码,这样更有针对性。因此,如果读者对于前面的题目分析有疑惑或者不理解的地方,请仔细阅读代码及旁边注释,一定会对你有所启发,帮助你的理解!!

(1)主函数

TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
	//_buildTree本题因为需要递归实现,因此需要借助一个递归函数。
       return _buildTree(preorder,0,preorder.size()-1,inorder,0,inorder.size()-1);
    }

我在这里要详细说明一下这个递归函数的各个参数及作用
第一个参数:就是前序遍历的vector,没有太多需要解释的
第二个参数:preStart,就是在子问题种前序的起始位置。详细的说,就是我们在确定根以后,我们就要递归左右子树,左右子树的起始位置是哪里就要确定。
第三个参数:preEnd:就是在子问题种前序的终止位置,这样就保证preStart与preEnd之间是子问题的结点序列。
第四个参数就是中序遍历的vector
第五个参数:inStart,就是在子问题中中序遍历的起始位置
第六个参数:inEnd,就是在子问题种中序遍历的结束位置

(2)递归函数

	TreeNode* _buildTree(vector<int>& preorder,int preStart,int preEnd,vector<int>&inorder,int inStart,int inEnd)
    {
        if(preStart>preEnd)
        {
            return nullptr;
        }
        //我们可以直接确定根节点,所以我们首先创建出根节点
        TreeNode* root = new TreeNode(preorder[preStart]);
        //找到根节点后,我们拿着根节点的值在中序遍历中找到对应位置,区分左右子树
        for(int i=inStart;i<=inEnd;i++)
        {
        	//找到根节点所在的中序遍历的位置
            if(inorder[i] == preorder[preStart])
            {
            	//由于递归函数完成子问题树的构建,所有让大问题的root左右子树分别链接即可
                root->left = _buildTree(preorder,preStart+1,preStart+i-inStart,inorder,inStart,i-1);
                root->right = _buildTree(preorder,preStart+i-inStart+1,preEnd,inorder,i+1,inEnd);
            }
        }
        return root;
    }

参数区间的决定

关键就是在递归子问题的时候传参数是多少。
在这里插入图片描述在这里插入图片描述
size:size是左子树中的结点个数所以size = i-inStart
所以:root->left = _buildTree(preorder,preStart+1,preStart+i-inStart,inorder,inStart,i-1);
xxxxxxroot->right = _buildTree(preorder,preStart+i-inStart+1,preEnd,inorder,i+1,inEnd);
读者自行比较即可理解

递归结束的条件

接下来就是判断如何结束递归,就是递归函数中的第一个if。之前我们提到过,如果子问题子树的区间不存在就可以结束循环了,那么怎么才叫不存在呢?
我们刚刚获得了每一个子树的前序的范围【preStart,preEnd】,如果preStart==preEnd时候,就说明子树还有一个结点,仍然需要循环,但是有没有可能preStart>preEnd呢?答案是肯定的。我们发现递归子问题的时候preStart = preStart+1,preStart不断增大,而递归子问题时preEnd = preStart+size-1。
分析比较得:当子树只有一个结点(size == 1)是,preStart == preEnd。再递归一次后,size == 0,因此preStart > preEnd。就说明没有子树了,可以返回nullptr了。
所以得到代码:if (preStart>preEnd) return nullptr;

总结

xxxx看到二叉树问题,我们首相应该想到的就是函数递归,因而二叉树具有很好的“递归特性”,每一个子树都是二叉树,都满足树的特性,子问题具有一样的特性就可以使用递归算法。其次我们应该明确知道,二叉树的“前、中、后,层序遍历”,并且知道他们之间的关系联系以及区别。在有以上的思想以及储备知识后,我们就可以写出具有一定思路的代码逻辑。这道题还有一个比较重要的地方就是控制子问题的前序、中序vector的范围界限。真正保证子问题与原问题的统一
xxxx这就是这道题的完整解析,如果大家有更好的思路,或者我代码中可优化的地方,请指出,我一定虚心学习。希望我们一起学习,一起进步!!

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-14 13:36:45  更:2021-09-14 13:37:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:39:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码