【LeetCode二叉树#11】最大二叉树(构造二叉树)
最大二叉树
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
- 二叉树的根是数组中的最大元素。
- 左子树是通过数组中最大值左边部分构造出的最大二叉树。
- 右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
示例 :

提示:
给定的数组的大小在 [1, 1000] 之间。
思路
就按照题意来就行,这里给了一种二叉树的构造规则,根据该规则构造的二叉树称为最大二叉树
模拟一下整个流程:
给了一个数组输入[3,2,1,6,0,5]
先找出其中的最大值,即6。该值最为最大二叉树的根节点
然后上述数组被分为了两部分:[3,2,1] 和 [0,5]
左边部分用于构建最大二叉树的左分支
右边部分用于构建最大二叉树的右分支
先来看左边子树(以 6 为根节点),在左数组中找出最大值,即3。该值为最大二叉树的左子树的根节点
于是 [3,2,1] 又被分成了 [] (左边没有数值了)和 [2,1] ,本次分割后左边数组是没有值了,因此以 3 为根节点的左子树也没有了
因为 [2,1] 属于 [3,2,1] 的 "右部分" ,所以要用来构建以 3 为根节点的右子树
以此类推将剩下的数处理完毕
右边子树(以 6 为根节点)的构建过程同理
可见,上述过程是递归的经典应用场景
代码分析
1、确定递归函数的参数和返回值
题干给了,输入是一个整数数组,那递归函数的输入应该也是这个
然后最后的结果是构造一个最大二叉树,那么返回值应该是二叉树的根节点
这里可以直接用模板给的函数就行
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
}
};
2、确定终止条件
题干说了,输入数组大小一定大于1,那么不用考虑小于1的情况
当输入数组大小为1时(经过不断的递归分割最后肯定都是1),说明已经到了叶子节点
那么递归构造应该结束,此时需要创建一个新节点来保存当前数组的值,并返回该节点
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
//定义一个新节点用于保存数组的最后一个值
TreeNode* node;
if(num.size() == 1){
node->val = num[0];
return node;
}
}
};
3、确定单层处理逻辑
一共分为三步:
- 遍历输入数组,确定当前最大值。最大值本身用于构造根节点,下标则用于分割数组
- 在最大值下标所在的左区间构造左子树
- 在最大值下标所在的右区间构造右子树
第一步,遍历输入数组,确定当前最大值。最大值本身用于构造根节点,下标则用于分割数组对不
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
//定义一个新节点用于保存数组的最后一个值
TreeNode* node;
if(num.size() == 1){
node->val = num[0];
return node;
}
//分别定义用于存放最大值及其下标的变量
int maxValue = 0;
int maxValueIndex = 0;
//遍历最大值
for(int i = 0; i < nums.size(); ++i){
if(nums[i] > maxValue){
maxValue = nums[i];
maxValueIndex = i;
}
}
//创建根节点
TreeNode* node = new TreeNode(maxValue);
}
};
第二步,最大值所在的下标左区间 构造左子树
注意,需要判断左区间是否有值(继续递归的条件是至少得有一个值吧),没有就直接返回node
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
//定义一个新节点用于保存数组的最后一个值
if(num.size() == 1){
TreeNode* node = new TreeNode(nums[0]);
return node;
}
//分别定义用于存放最大值及其下标的变量
int maxValue = 0;
int maxValueIndex = 0;
//遍历最大值
for(int i = 0; i < nums.size(); ++i){
if(nums[i] > maxValue){
maxValue = nums[i];
maxValueIndex = i;
}
}
//创建根节点
TreeNode* node = new TreeNode(maxValue);
//处理左区间,构建左子树
//先判断左区间是否有值
if(maxValueIndex > 0){
//分割得到左区间数组
vector<int> leftVec(nums.begin(), nums.begin() + maxValueIndex);
//利用左区间递归构建左子树
node->left = constructMaximumBinaryTree(leftVec);
}
//处理右区间,构建右子树
//先判断右区间是否有值
if(maxValueIndex < nums.size() - 1){
//分割得到右区间数组
vector<int> leftVec(nums.begin() + maxValueIndex + 1, nums.end());
//利用右区间递归构建右子树
node->left = constructMaximumBinaryTree(leftVec);
}
return node;
}
};
构建二叉树思路总结
通过这三题构建二叉树的题目(从中序与后序遍历序列构造二叉树、从中序与后序遍历序列构造二叉树以及 本题 ),可以总结出一些共同点
0、如果使用递归方式,返回值一定是节点类型
1、不论按怎样的规则构造,最开始一定需要寻找二叉树的根节点
2、按根节点分割遍历数组时,要坚持循环不变量,并且注意**要跳过根节点
【LeetCode二叉树#11】最大二叉树(构造二叉树)的更多相关文章
- Leetcode 1008. 先序遍历构造二叉树
1008. 先序遍历构造二叉树 显示英文描述 我的提交返回竞赛 用户通过次数169 用户尝试次数183 通过次数171 提交次数247 题目难度Medium 返回与给定先序遍历 preorder ...
- LeetCode(106):从中序与后序遍历序列构造二叉树
Medium! 题目描述: 根据一棵树的中序遍历与后序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 posto ...
- LeetCode(105):从前序与中序遍历序列构造二叉树
Medium! 题目描述: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inor ...
- Leetcode 106. 从中序与后序遍历序列构造二叉树
题目链接 https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/descri ...
- Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树
Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树 Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序 ...
- Leetcode:1008. 先序遍历构造二叉树
Leetcode:1008. 先序遍历构造二叉树 Leetcode:1008. 先序遍历构造二叉树 思路 既然给了一个遍历结果让我们建树,那就是要需要前序中序建树咯~ 题目给的树是一颗BST树,说明中 ...
- 代码随想录算法训练营day18 | leetcode 513.找树左下角的值 ● 112. 路径总和 113.路径总和ii ● 106.从中序与后序遍历序列构造二叉树
LeetCode 513.找树左下角的值 分析1.0 二叉树的 最底层 最左边 节点的值,层序遍历获取最后一层首个节点值,记录每一层的首个节点,当没有下一层时,返回这个节点 class Solutio ...
- leetcode 105 106 从前序与中序遍历序列构造二叉树 从中序与后序遍历序列构造二叉树
题目: 105 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = ...
- [leetcode]从中序与后序/前序遍历序列构造二叉树
从中序与后序遍历序列构造二叉树 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 po ...
- [Leetcode] Construct binary tree from preorder and inorder travesal 利用前序和中续遍历构造二叉树
Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume tha ...
随机推荐
- [转帖]gcc与makefile常用操作(绝对常用,也绝对够用)
makefile与gcc常用操作 一.温故知新 1.可执行程序的生成过程 2.gcc的常用操作 二.make操作 三.编写Makefile文件时常用操作 注意:在Makefile文件中 空格和缩进是完 ...
- [转帖]【JVM】JVM源码分析之Metaspace解密
概述 metaspace,顾名思义,元数据空间,专门用来存元数据的,它是jdk8里特有的数据结构用来替代perm,这块空间很有自己的特点,前段时间公司这块的问题太多了,主要是因为升级了中间件所致,看到 ...
- [转帖]kubelet 原理解析六: 垃圾回收
https://segmentfault.com/a/1190000022163856 概述 在k8s中节点会通过docker pull机制获取外部的镜像,那么什么时候清除镜像呢?k8s运行的容器又是 ...
- DBeaver连接国产信创数据库的步骤
DBeaver连接国产信创数据库的步骤 本次连接使用的数据库类型 1.达梦 2.神通 3.人大金仓 4.瀚高 安装DBeaver 通过官网或者是其他网站下载最新的数据库介质 之后的操作为: 这次不感谢 ...
- Mybatis 拦截器实现单数据源内多数据库切换 | 京东物流技术团队
物流的分拣业务在某些分拣场地只有一个数据源,因为数据量比较大,将所有数据存在一张表内查询速度慢,也为了做不同设备数据的分库管理,便在这个数据源内创建了多个不同库名但表完全相同的数据库,如下图所示: 现 ...
- 解决刷新SwaggerUi控制台报错
一.问题描述 在浏览器刷新SwaggerUI的页面,控制台就报错: java.lang.NumberFormatException: For input string: "" at ...
- 你不知道的<input type="file">的小秘密
限制file上传类型 很多时候,我们都需要使用 <input type="file"> 进行文件上传. 在上传的时候,我们需要对文件类型进行限制. 如果上传图片的时候. ...
- 【分享代码片段】terraform中,如何从刚刚创建的 deployment 中获得所有容器的名字和 ip
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 不好意思,刚刚才开始用 terraform,或许是更好的办 ...
- 在K8S中各个组件及其作用?
Kubernetes(简称K8s)是一个强大的容器编排系统,其主要组件及其作用如下: kube-apiserver: 集群的主入口点,提供了RESTful API接口供用户或内部组件与集群进行交互.它 ...
- Java 自增自减运算符和移位运算符介绍
摘自 JavaGuide (「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识.准备 Java 面试,首选 JavaGuide!) 自增自减运算符 在写代码的过程中,常见的 ...