这道题很简单,主要是两点:一是确定根节点,二是维护集合nums。剩下的直接交给递归就OK了。根节点很好确定,直接遍历nums即可,取出最大值作为根节点。维护集合nums:将根节点在nums中左侧的集合赋值给根节点左子树的nums,将根节点在nums中右侧的集合赋值给根节点右子树的nums。
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
//确定递归结束条件
if(nums.empty()) return nullptr;
//寻找根节点
int max=INT_MIN;
int index;
for(int i=0;i<nums.size();i++)
{
if(nums[i]>max)
{
max=nums[i];
index=i;
}
}
//建立根节点
TreeNode* root=new TreeNode(nums[index]);
//维护集合nums
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;
}
};
这里要同时遍历两颗二叉树,两棵树需要用同一种遍历方式来保证每次遍历的相对位置相同。然后就是判断两棵树当前结点的情况,两节点都为空、仅有一个结点为空、都不为空。
都为空:返回空
一个结点为空:返回另一个不为空的结点
都不为空:返回两结点相加后的结点
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
//确定结束条件
if(root1==nullptr && root2==nullptr) return nullptr;
else if(root1==nullptr) return root2;
else if(root2==nullptr) return root1;
//在root1和root2中选一棵树作为将要返回的新树
//这里选择root1作为新树
root1->val+=root2->val;
//连接左右子树
root1->left=mergeTrees(root1->left,root2->left);
root1->right=mergeTrees(root1->right,root2->right);
return root1;
}
};
这里要理解什么是二叉搜索树,简单来说就是当前结点左子树的每一个值都比当前结点小 ,当前结点右子树的每一个值都比当前结点大 。这里我们很容易就可以判断该结点的值与左右孩子结点的值的大小情况,但是我们很难去判断该结点的值是否大于或小于它的左右子树的每一个值。
我们需要用到二叉搜索树的一个特性:二叉搜索树中序遍历的值是单调递增的。知道这个特性问题就简单多了。可以声明一个变量来存储当前结点的上一个结点的值,比较当前结点和变量的大小,然后不断维护变量的值。
class Solution {
public:
long long n=LONG_MIN;
bool isValidBST(TreeNode* root) {
if(root==nullptr) return true;
//前
bool left=isValidBST(root->left);
//中
if(root->val<=n) return false;
n=root->val; //维护变量的值
//后
bool right=isValidBST(root->right);
return left&&right;
}
};
注意:变量一定要使用long long类型的。用int将不能通过全部测试,因为如果中序遍历的第一个值等于INT_MIN ,那么将会直接返回false。