给定一个不重复的整数数组 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
中的所有整数 互不相同
这些题目都有很多种解法,我先来发下我自己写的一种很容易理解的写法。
**
* 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) {
TreeNode* root =new TreeNode(0);
if(nums.size()==1) {
root->val = nums[0];
return root;
} //这个是递归出去的条件
int max_num =0;
int index =0;
for(int i = 0; i<nums.size();i++){ //获得了nums的最大值和最大值的索引
if(nums[i]>max_num){
max_num=nums[i];
index = i;
}
}
root->val =max_num;
//把根节点的值设计为最大
// 先划分左区间
if(index>0){ // 这里加了判断是为了不让空节点进入递归
vector<int> left_nums(nums.begin(), nums.begin() + index);
root->left = constructMaximumBinaryTree(left_nums);
}
// 右区间
if(index<nums.size()-1){ // 这里加了判断是为了不让空节点进入递归
vector<int> right_nums(nums.begin() + index + 1, nums.end());
root->right =constructMaximumBinaryTree(right_nums);
}
//重点是怎么判断是左区间还是右区间?
return root;
}
};
这个重点思想是构造左右区间,以最大值为中间点,index左边是左区间,右边是右区间。因此,左区间存在的条件是,index>0,既有左区间,同理,index<nums.size()-1,既有右区间。因此,进行递归把左区间放进去,用根节点的左孩子接住它,右边用根节点的右孩子去接住它。
因此,在这里用的类似于前序遍历,中,左,右。递归进去左(root的左孩子去接住他,root的右孩子去接住他)