思路:构造二叉树一般都用前序遍历,中左右,可以优先处理构造中节点,再递归构造左右子树。
题解分步:
第一步.找到该数组中最大的元素,并记录其数组下标(方便分割数组),也是切割点。
第二步.中,构造该最大值的节点
第三步.左,把切割点(不包含切割点)左边的数组传入递归构造左子树
第四步.右,切割点右边数组传入递归构造右子树
最后,返回其根节点
注:分割数组必须遵循循环不变量原则,下面分割区间是左边右开
代码:
TreeNode* constructMaximumBinaryTree(vector& nums) {
if(nums.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 newVec(nums.begin(),nums.begin() + MaxValueindex);//切割左数组,区间左闭右开,[0,MaxValueindex)
node->left = constructMaximumBinaryTree(newVec);//构造左子树
}
//右,切割点右边至少要有一个元素
if(MaxValueindex < (nums.size() - 1)){
vector newVec(nums.begin() + MaxValueindex + 1,nums.end());//切割右数组,区间左闭右开,[MaxValueindex+1,end)
node->right = constructMaximumBinaryTree(newVec);//构造右子树
}
return node;
}
思路:合并两颗二叉树可以看作构造一颗新二叉树,比较直观的遍历顺序是前序,中后序也可以。
代码:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
//节点1为空,2不为空,则把2节点返回;
if(root1 == nullptr) return root2;
if(root2 == nullptr) return root1;
//中,节点12都不为空,两值相加到一个新节点
TreeNode* root = new TreeNode(root1->val + root2->val);
//左
root->left = mergeTrees(root1->left,root2->left);
//右
root->right = mergeTrees(root1->right,root2->right);
return root;
}
代码:
TreeNode* searchBST(TreeNode* root, int val) {
//中,值相等则找到子树,若找不到该值的节点,root会遍历到空节点,直接返回该节点null即可
//注:条件左右顺序不能反,不能访问空指针的val
if(root == nullptr || root->val == val) return root;
//左
if(root->val > val) return searchBST(root->left,val);
//右
if(root->val < val) return searchBST(root->right,val);
return nullptr;
}
解1:二叉搜索树的特性可以用前序遍历,可以得到一个单调递增的序列,遍历完整颗树再判断数组是否单增。
解2:利用双指针,pre记录前一个节点,再与当前root节点比较数组,因为中序遍历,所以符合条件的二叉搜索树的值:左<中<右,也就是pre的值 代码:TreeNode* pre = nullptr;//记录前一个节点
bool isValidBST(TreeNode* root) {
if(root == nullptr) return true;//空节点也符合二叉搜索树
//左
bool left = isValidBST(root->left);
//中
if(pre!=nullptr && pre->val >= root->val) return false;
pre = root;
//右
bool right = isValidBST(root->right);
return left && right;//仅当左右子树都符合条件
}