首页 > 其他分享 >【LeetCode二叉树#11】最大二叉树(构造二叉树)

【LeetCode二叉树#11】最大二叉树(构造二叉树)

时间:2023-02-28 19:58:50浏览次数:53  
标签:11 node nums 最大值 LeetCode 二叉树 数组 节点

最大二叉树

力扣题目地址(opens new window)

给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

  • 二叉树的根是数组中的最大元素。
  • 左子树是通过数组中最大值左边部分构造出的最大二叉树。
  • 右子树是通过数组中最大值右边部分构造出的最大二叉树。

通过给定的数组构建最大二叉树,并且输出这个树的根节点。

示例 :

654.最大二叉树

提示:

给定的数组的大小在 [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、按根节点分割遍历数组时,要坚持循环不变量,并且注意**要跳过根节点

标签:11,node,nums,最大值,LeetCode,二叉树,数组,节点
From: https://www.cnblogs.com/DAYceng/p/17165734.html

相关文章

  • 11. Kubernetes - Ingress
    Ingress前面知道了可以使用NodePort和LoadBlancer类型的Service可以把应用暴露给外部用户使用,这对于小规模的应用来说确实没多大问题,但是当你的应用越来越多的时候,......
  • 二叉树的前序,中序,后序,顺序遍历
    实体类:packagecom.test.知识点.数据结构.树.二叉树;importlombok.Data;/***CreatedbyAdministratoron2023/2/28.*/@DatapublicclassBinaryTree{......
  • #yyds干货盘点# LeetCode程序员面试金典:珠玑妙算
    题目:珠玑妙算游戏(thegameofmastermind)的玩法如下。计算机有4个槽,每个槽放一个球,颜色可能是红色(R)、黄色(Y)、绿色(G)或蓝色(B)。例如,计算机可能有RGGB4种(槽1为红色,槽2、3为绿......
  • #yyds干货盘点# LeetCode程序员面试金典:部分排序
    题目:给定一个整数数组,编写一个函数,找出索引m和n,只要将索引区间[m,n]的元素排好序,整个数组就是有序的。注意:n-m尽量最小,也就是说,找出符合条件的最短序列。函数返回值为[m,n],......
  • #yyds干货盘点# LeetCode面试题:搜索旋转排序数组
    1.简述:整数数组nums按升序排列,数组中的值互不相同。在传递给函数之前,nums在预先未知的某个下标k(0<=k<nums.length)上进行了旋转,使数组变为[nums[k],nums[k+1],......
  • #yyds干货盘点# LeetCode面试题:在排序数组中查找元素的第一个和最后一个位置
    1.简述:给你一个按照非递减顺序排列的整数数组nums,和一个目标值target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值target,返回 [-1,-1]......
  • 1140. 石子游戏 II (Medium)
    问题描述1140.石子游戏II(Medium)爱丽丝和鲍勃继续他们的石子游戏。许多堆石子排成一行,每堆都有正整数颗石子piles[i]。游戏以谁手中的石子最多来决出胜负。爱丽丝......
  • win11环境 cmd 命令窗口 sqlplus 命令无响应
    此问题疑似path环境变量过长导致,安装过程中已有类似提示 之前我是删除了部分环境变量后通过校验。安装完成后把path删除的环境变量再加上去隔天重启服务器后发现 ......
  • 1139. 最大的以 1 为边界的正方形 (Medium)
    问题描述1139.最大的以1为边界的正方形(Medium)给你一个由若干0和1组成的二维网格grid,请你找出边界全部由1组成的最大正方形子网格,并返回该子网格中的元素......
  • 【扫描线】LeetCode 253. 会议室 II
    题目链接253.会议室II思路这道题非常类似于坐公交车上下车。样例中intervals=[[0,30],[5,10],[15,20]]可以这么拆解上车:[0,+1],[5,+1],[15,+1]下车:[10,-......