前言
二叉树篇,继续。
记录 五十一【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;
}
//找最大值确定根节点,同时确定最大值的下标index
int 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;//因为题目中说元素值最小是0 int 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.从中序与后序遍历序列构造二叉树】可以归为一类。
可以改进成:只传递下标值,每次不创建新数组,不开辟新空间更好。
(欢迎指正,转载标明出处)