前言
二叉树篇,继续。
记录 五十一【654.最大二叉树】
一、题目阅读
给定一个不重复的整数数组 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 中的所有整数 互不相同
二、尝试实现
思路
- 题目定义如何构建最大二叉树,按照题目的递归思路即可以实现。
- 递归返回值:返回子树(树)的根节点;
- 递归参数:左子树/右子树的数组,所以参数vector< int >
- 递归终止条件:当数组为空,返回nullptr;当数组只有一个,可直接返回叶子节点(等同于根节点)。
- 递归逻辑:
- 找到最大值。
- 分割nums。
- 总结:整体思路类似记录 五十【106.从中序与后序遍历序列构造二叉树】拿到中间节点后分割中序数组。
代码实现
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:TreeNode* constructMaximumBinaryTree(vector<int>& nums) {if(nums.size() == 0) return nullptr;if(nums.size() == 1){ //叶子自己就是根TreeNode* root = new TreeNode(nums[0]);return root;}//找最大值确定根节点,同时确定最大值的下标indexint maxnum = INT_MIN;int index = 0;for(int i = 0;i < nums.size();i++){if(nums[i] > maxnum){maxnum = nums[i];index = i;}}TreeNode* root = new TreeNode(maxnum);//区间左闭右开vector<int> left(nums.begin(),nums.begin()+index);vector<int> right(nums.begin()+index+1,nums.end());root->left = constructMaximumBinaryTree(left);root->right = constructMaximumBinaryTree(right);return root;}
};
三、参考学习
参考学习链接
学习内容
-
题目属于构造二叉树类型,遍历顺序:前序——中左右。类似:记录 五十【106.从中序与后序遍历序列构造二叉树】 ,同理构造顺序——中左右。
-
思路同理。和二、中的思路一致。但是有点区别——如果终止条件判断nums是否为空,那么“传递”下一层不用判断index值;如果终止条件默认nums不为空,那么“传递”下一层要if(index条件)。
-
代码优化:不创建新数组传递。只传递下标值:
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/ class Solution { public:TreeNode* build(vector<int>& nums,int begin,int end){if(begin == end) return nullptr;if(end - begin == 1){TreeNode* root = new TreeNode(nums[begin]);return root;}int maxvalue = 0;//因为题目中说元素值最小是0int index = begin;//从begin开始判断for(int i = begin;i < end;i++){if(nums[i] > maxvalue){maxvalue = nums[i];index = i;}}int leftbegin = begin;int leftend = index;int rightbeign = index+1;int rightend = end;TreeNode* root = new TreeNode(maxvalue);root->left = build(nums,leftbegin,leftend);root->right = build(nums,rightbeign,rightend);return root;}TreeNode* constructMaximumBinaryTree(vector<int>& nums) {return build(nums,0,nums.size());} };
总结
记录 五十一【654.最大二叉树】和记录 五十【106.从中序与后序遍历序列构造二叉树】可以归为一类。
可以改进成:只传递下标值,每次不创建新数组,不开辟新空间更好。
(欢迎指正,转载标明出处)