代码随想录算法训练营day17 | 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
654.最大二叉树
点击查看代码
class Solution {
public:
//找到[left, right)子树内的根节点,并与其左子树和右子树进行连接,最后返回子树的根节点
TreeNode *searchRoot(vector<int> &nums, int left, int right) {
if(left == right) return nullptr;
int maxNum, maxIndex;
//注意此处i < right而不是i < nums.size(),因为要处理的是传入的子树,而不是整棵树
for(int i = left; i < right; ++i) {
if(i == left) {
maxNum = nums[left];
maxIndex = left;
}
if(nums[i] > maxNum) {
maxNum = nums[i];
maxIndex = i;
}
}
TreeNode *root = new TreeNode(maxNum);
if(right - left == 1) return root; //递归终止条件二:叶子节点直接返回,无需再递归构造子树
int leftBegin = left, leftEnd = maxIndex;
int rightBegin = maxIndex + 1, rightEnd = right;
root->left = searchRoot(nums, leftBegin, leftEnd);
root->right = searchRoot(nums, rightBegin, rightEnd);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return searchRoot(nums, 0, nums.size());
}
};
与中序+前/后序构造二叉树的思路基本一致
根节点自顶向下找,边自底向上连接
什么时候递归函数前面加if,什么时候不加if:
一般情况来说:如果让空节点(空指针)进入递归,就不加if,如果不让空节点进入递归,就加if限制一下, 终止条件也会相应的调整(或无需终止条件)。
617.合并二叉树
解法一:自创解法
点击查看代码
class Solution {
public:
void preOrder(TreeNode* root1, TreeNode* root1_parent, TreeNode* root2, TreeNode* root2_parent) {
//递归终止条件1:
if(root1 == nullptr && root2 == nullptr) return;
//递归终止条件2
if(root1 != nullptr && root2 == nullptr) return;
//递归终止条件3
if(root1 == nullptr && root2 != nullptr) {
if(root2 == root2_parent->left) root1_parent->left = root2;
if(root2 == root2_parent->right) root1_parent->right = root2;
return;
}
if(root1 != nullptr && root2 != nullptr) {
//根
root1->val += root2->val;
//左
preOrder(root1->left, root1, root2->left, root2);
//右
preOrder(root1->right, root1, root2->right, root2);
}
}
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
//由于整颗树的父节点为空,root1 == nullptr && root2 != nullptr时进行递归会导致操作空指针,故提前剪枝
if(root1 == nullptr) return root2;
preOrder(root1, nullptr, root2, nullptr);
return root1;
}
};
解法二:代码随想录解法,值得学习
点击查看代码
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (t1 == NULL) return t2; // 如果t1为空,合并之后就应该是t2
if (t2 == NULL) return t1; // 如果t2为空,合并之后就应该是t1
// 修改了t1的数值和结构
t1->val += t2->val; // 中
t1->left = mergeTrees(t1->left, t2->left); // 左
t1->right = mergeTrees(t1->right, t2->right); // 右
return t1;
}
};
700.二叉搜索树中的搜索
点击查看代码
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root == nullptr) return nullptr;
else if(root->val == val) return root;
else if(root->val < val) return searchBST(root->right, val);
else return searchBST(root->left, val);
}
};
二叉搜索树/二叉排序树的特点为左 < 中 < 右,找到空节点/失败节点即空指针时即查找失败,返回nullptr
递归时,要根据root->val与val的大小关系选择左或右(只选择一个方向)进行递归查找,而不是对整棵树进行递归遍历
98.验证二叉搜索树
点击查看代码
class Solution {
public:
int maxNum;
bool result = true;
bool firstEle = true;
void inorder(TreeNode* root) {
if(root == nullptr) return;
inorder(root->left);
//第一个元素需要作为初始最大值,此条件非常关键,不加的话会导致很多特殊用例无法通过,
//如首元素为INT_MIN,而maxNum若也初始化为INT_MIN,会导致result直接变为false,如[INT_MIN,1],int maxNum = INT_MIN时
if(firstEle == true || root->val > maxNum) {
maxNum = root->val;
firstEle = false;
}
else result = false;
inorder(root->right);
}
bool isValidBST(TreeNode* root) {
inorder(root);
return result;
}
};
2025/03/01

浙公网安备 33010602011771号