题目链接:https://leetcode.cn/problems/maximum-binary-tree/description/

题目叙述

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

创建一个根节点,其值为 nums 中的最大值。

递归地在最大值 左边 的 子数组前缀上 构建左子树。

递归地在最大值 右边 的 子数组后缀上 构建右子树。

返回 nums 构建的 最大二叉树 。

示例 1:

输入:nums = [3,2,1,6,0,5]

输出:[6,3,5,null,2,0,null,null,1]

解释:递归调用如下所示:

  • [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。

    • [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。

      • 空数组,无子节点。
      • [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
        • 空数组,无子节点。
        • 只有一个元素,所以子节点是一个值为 1 的节点。
    • [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
      • 只有一个元素,所以子节点是一个值为 0 的节点。
      • 空数组,无子节点。

示例 2:

输入:nums = [3,2,1]

输出:[3,null,2,null,1]

提示:

1 <= nums.length <= 1000

0 <= nums[i] <= 1000

nums 中的所有整数 互不相同

思路:

构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。

我们来走一下递归的三步法:

  1. 递归函数的参数和返回值:返回值明显为TreeNode的节点类型,参数我们需要传入一个数组

  2. 递归结束的条件:题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。

    那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。

		TreeNode* node = new TreeNode(0);
if (nums.size() == 1) {
node->val = nums[0];
return node;
}

3.递归的单层逻辑:

我们需要找出这个数组中的最大值,然后对这个数组进行分割,最大值左边的数组来构造左子树,最大值右边的数组来构造右子树,不过在此之前,我们还得找到最大值和最大值所对应的下标

		//找到了这个数组中的最大的元素和最大元素所在的下标
int maxValue = 0;
int index = 0;
for (int i = 0; i < nums.size(); i++) {
if (nums[i] > maxValue) {
index = i;
maxValue = nums[i];
}
}
//对根节点进行赋值
node->val = maxValue;

然后就是对根节点node的左子树和右子树进行构造的过程,我们可以使用两个数组,来存储最大值左边的序列和最大值右边的序列

		if (index >= 1) {
//因为vector的拷贝构造函数是左开右闭的逻辑
vector<int> newVec(nums.begin(), nums.begin() + index);
node->left = constructMaximumBinaryTree(newVec);
}
//确保右边子树的元素个数≥1
if ((nums.size() - 1) - index > 0) {
vector<int> newVec(nums.begin() + index + 1, nums.end());
node->right = constructMaximumBinaryTree(newVec);
}
return node;

这几步做完以后,基本就完成了


//最大二叉树
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
TreeNode* node = new TreeNode(0);
if (nums.size() == 1) {
node->val = nums[0];
return node;
}
//找到了这个数组中的最大的元素和最大元素所在的下标
int maxValue = 0;
int index = 0;
for (int i = 0; i < nums.size(); i++) {
if (nums[i] > maxValue) {
index = i;
maxValue = nums[i];
}
}
//对根节点进行赋值
node->val = maxValue;
//对左子树进行构造(确保左边数组的元素个数≥1)
if (index >= 1) {
vector<int> newVec(nums.begin(), nums.begin() + index);
node->left = constructMaximumBinaryTree(newVec);
}
//确保右边子树的元素个数≥1
if ((nums.size() - 1) - index > 0) {
vector<int> newVec(nums.begin() + index + 1, nums.end());
node->right = constructMaximumBinaryTree(newVec);
}
return node;
}
};

进阶

我们可以不适用额外的数组空间,我们可以直接对传入的数组的下标进行操作

class Solution {
public:
TreeNode* traversal(vector<int> &nums,int left,int right){
//当左区间≥右区间,就返回
if(left>=right) return nullptr;
//记录最大值的下标
int maxValueIndex=left;
for(int i=left+1;i<right;i++){
if(nums[i]>nums[maxValueIndex]) maxValueIndex=i;
}
//构造根节点
TreeNode* node=new TreeNode(nums[maxValueIndex]);
//构造左子树和右子树
node->left=traversal(nums,left,maxValueIndex);
node->right=traversal(nums,maxValueIndex+1,right);
//返回根节点
return node;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return traversal(nums,0,nums.size());
}
};

总结

注意类似用数组构造二叉树的题目,每次分隔尽量不要定义新的数组,而是通过下标索引直接在原数组上操作,这样可以节约时间和空间上的开销。

什么时候递归函数前面加if,什么时候不加if?

其实就是不同代码风格的实现,一般情况来说:如果让空节点(空指针)进入递归,就不加if,如果不让空节点进入递归,就加if限制一下, 终止条件也会相应的调整。

LeetCode654. 最大二叉树的更多相关文章

  1. [Swift]LeetCode654. 最大二叉树 | Maximum Binary Tree

    Given an integer array with no duplicates. A maximum tree building on this array is defined as follo ...

  2. LeetCode通关:连刷三十九道二叉树,刷疯了!

    分门别类刷算法,坚持,进步! 刷题路线参考:https://github.com/youngyangyang04/leetcode-master 大家好,我是拿输出博客来督促自己刷题的老三,这一节我们 ...

  3. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  4. 二叉树的递归实现(java)

    这里演示的二叉树为3层. 递归实现,先构造出一个root节点,先判断左子节点是否为空,为空则构造左子节点,否则进入下一步判断右子节点是否为空,为空则构造右子节点. 利用层数控制迭代次数. 依次递归第二 ...

  5. c 二叉树的使用

    简单的通过一个寻找嫌疑人的小程序 来演示二叉树的使用 #include <stdio.h> #include <stdlib.h> #include <string.h& ...

  6. Java 二叉树遍历右视图-LeetCode199

    题目如下: 题目给出的例子不太好,容易让人误解成不断顺着右节点访问就好了,但是题目意思并不是这样. 换成通俗的意思:按层遍历二叉树,输出每层的最右端结点. 这就明白时一道二叉树层序遍历的问题,用一个队 ...

  7. 数据结构:二叉树 基于list实现(python版)

    基于python的list实现二叉树 #!/usr/bin/env python # -*- coding:utf-8 -*- class BinTreeValueError(ValueError): ...

  8. [LeetCode] Path Sum III 二叉树的路径和之三

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  9. [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  10. [LeetCode] Verify Preorder Serialization of a Binary Tree 验证二叉树的先序序列化

    One way to serialize a binary tree is to use pre-oder traversal. When we encounter a non-null node, ...

随机推荐

  1. 【昇腾开发全流程】AscendCL开发板模型推理

    前言 学会如何安装配置华为云ModelArts.开发板Atlas 200I DK A2. 并打通一个Ascend910训练到Ascend310推理的全流程思路. 在本篇章,我们继续进入推理阶段! 推理 ...

  2. NOIP模拟89(多校22)

    T1 谜之阶乘 解题思路 二分答案,发现 \(a-b\) 至多为 19,毕竟 \(20!\) 已经大于 \(10^{18}\) 了. 对于每一种可能的差值,每一次二分 \(b+1\) 直接枚举乘积进行 ...

  3. android端http请求重发问题定位过程

    昨天生产系统上报出一个问题:用户做一次扫码交易,出现了两条交易记录.幸好支付渠道对支付码有限制只成功了一笔,没有出现多扣钱的问题.现在我们要排查一下,为什么做一次操作会出现两条交易记录.我们的后台服务 ...

  4. uniapp 富文本图片100%显示

    下面的这个方法是在百度上找的,但是老是报错,一直没找到原因,索性自己就挨个检查了下,发现在过滤之前需要对传过来的值进行检测,是字符串才能让这个方法执行 filters: { formatRichTex ...

  5. INFINI Gateway 与华为鲲鹏完成产品兼容互认证

    何为华为鲲鹏认证 华为鲲鹏认证是华为云围绕鲲鹏云服务(含公有云.私有云.混合云.桌面云)推出的一项合作伙伴计划,旨在为构建持续发展.合作共赢的鲲鹏生态圈,通过整合华为的技术.品牌资源,与合作伙伴共享商 ...

  6. 基于 Easysearch kNN 搭建即时图片搜索服务

    环境准备 启动 Easysearch 服务: # Make sure your vm.max_map_count meets the requirement sudo sysctl -w vm.max ...

  7. 给 ES 插上向量检索的翅膀 | DataFunSummit 2023 峰会演讲内容速达

    近日,由 DataFun 主办的 DataFunSummit 2023 数据基础架构峰会 圆满落下帷幕,本次峰会邀请了腾讯.百度.字节.极限科技.Zilliz 等众多企业技术专家为大家带来分布式存储以 ...

  8. 如果你也用过 struts2.简单介绍下 springMVC 和 struts2 的区别有哪些?

    a.springmvc 的入口是一个 servlet 即前端控制器,而 struts2 入口是一个 filter 过虑器. b.springmvc 是基于方法开发(一个 url 对应一个方法),请求参 ...

  9. vue使用wx-open-launch-weapp

    vue使用wx-open-launch-weapp 官方文档 <template> <div style="width: 100%; height: 100%;" ...

  10. Excel Wps 透视表去重计数方法

    Excel Wps 透视表去重计数方法 在处理表格,遇到处理根据某个列去重后统计数量,而不是仅仅统计数量.在网上查找资料,不确定EXCEL或者WPS某个版本可以支持该功能的实现. 折中的方案,分两步来 ...