654.最大二叉树
采用递归的方法,总体思路为先找到最大元素作为根节点,然后以此对于左右进行分割,形成新的数组,在新数组中继续以上的行为,直到新数组仅剩1个元素退出递归
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
TreeNode *node = new TreeNode(0);
if(nums.size()==1){
node->val = nums[0];
return node;
}
int maxVal = 0;
int maxValIndex = 0;
for (int i = 0;i < nums.size();i++) {
if(nums[i]>maxVal){
maxVal = nums[i];
maxValIndex = i;
}
}
node->val = maxVal;
if(maxValIndex>0){
vector<int> newVec(nums.begin(),nums.begin()+maxValIndex);
node->left=constructMaximumBinaryTree(newVec);
}
if(maxValIndex<nums.size()-1){
vector<int> newVec(nums.begin()+maxValIndex,nums.end());
node->right = constructMaximumBinaryTree(newVec);
}
return node;
}
};
但是这个代码在力扣上无法提交,因为量太大:
进行优化,不再创建新的数组,而是在原数组上尽心操作:
代码中定义了一个名为Solution
的类,该类包含一个私有成员函数traversal
和一个公共成员函数constructMaximumBinaryTree
。
traversal
函数用于递归地构造最大二叉树。它接受一个整数向量nums
、左边界left
和右边界right
作为参数,并返回构造的二叉树的根节点。
在函数中,首先判断左边界是否大于等于右边界,如果是,说明当前区间内没有节点,返回空指针。
然后,通过遍历区间内的节点,找到值最大的节点,将其作为当前区间的根节点。
接下来,递归地构造根节点的左子树和右子树。左子树的节点范围是左闭右开区间[left, maxValueIndex)
,右子树的节点范围是左闭右开区间[maxValueIndex + 1, right)
。
最后,将构造的左子树和右子树分别赋给根节点的左指针和右指针,并返回根节点。
constructMaximumBinaryTree
函数是公共成员函数,用于调用traversal
函数并返回构造的最大二叉树的根节点。它接受一个整数向量nums
作为参数,并调用traversal
函数来构造最大二叉树。
整个程序的逻辑是通过递归地将每个区间划分为左右两个子区间,并在每个子区间中选取值最大的节点作为当前区间的根节点,直到区间为空为止。最终返回构造的最大二叉树的根节点。
class Solution {
private:
// 在左闭右开区间[left, right),构造二叉树
TreeNode* traversal(vector<int>& nums, int left, int right) {
if (left >= right) return nullptr;
// 分割点下标:maxValueIndex
int maxValueIndex = left;
for (int i = left + 1; i < right; ++i) {
if (nums[i] > nums[maxValueIndex]) maxValueIndex = i;
}
TreeNode* root = new TreeNode(nums[maxValueIndex]);
// 左闭右开:[left, maxValueIndex)
root->left = traversal(nums, left, maxValueIndex);
// 左闭右开:[maxValueIndex + 1, right)
root->right = traversal(nums, maxValueIndex + 1, right);
return root;
}
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
return traversal(nums, 0, nums.size());
}
};
617.合并二叉树
本体采用递归思路:
输入两个二叉树的根节点,输出的是一个二叉树的根节点;
终止条件为两个树中的一个为空;
单层循环条件就是以一个树为基础,加上另一个树的值;
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1==nullptr) return root2;
if(root2==nullptr) return root1;
root1->val += root2->val;
root1->left = mergeTrees(root1->left, root2->left);
root1->right = mergeTrees(root1->right, root2->right);
return root1;
}
};
迭代法:
class Solution {
public:
TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
if (t1 == NULL) return t2;
if (t2 == NULL) return t1;
queue<TreeNode*> que;
que.push(t1);
que.push(t2);
while(!que.empty()) {
TreeNode* node1 = que.front(); que.pop();
TreeNode* node2 = que.front(); que.pop();
// 此时两个节点一定不为空,val相加
node1->val += node2->val;
// 如果两棵树左节点都不为空,加入队列
if (node1->left != NULL && node2->left != NULL) {
que.push(node1->left);
que.push(node2->left);
}
// 如果两棵树右节点都不为空,加入队列
if (node1->right != NULL && node2->right != NULL) {
que.push(node1->right);
que.push(node2->right);
}
// 当t1的左节点 为空 t2左节点不为空,就赋值过去
if (node1->left == NULL && node2->left != NULL) {
node1->left = node2->left;
}
// 当t1的右节点 为空 t2右节点不为空,就赋值过去
if (node1->right == NULL && node2->right != NULL) {
node1->right = node2->right;
}
}
return t1;
}
};
700.二叉搜索树中的搜索
采用递归法,输入需要搜索的二叉树和目标值,返回子二叉树;
终止条件为搜索到目标值
单层循环为当root->val>val时,searchBST(root->left,val);当root->val<val时,searchBST(root->right,val)
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root==nullptr||root->val==val)
return root;
TreeNode *result;
if(root->val>val)
result = searchBST(root->left, val);
if(root->val<val)
result = searchBST(root->right, val);
return result;
}
};
迭代法:
class Solution
{
public:
TreeNode *searchBST(TreeNode *root, int val)
{
while (root != NULL)
{
if (root->val > val)
root = root->left;
else if (root->val < val)
root = root->right;
else
return root;
}
return NULL;
}
};
98.验证二叉搜索树
采用先将二叉树转为数组,然后通过数组进行对比的方法
在转换成数组的过程中采用递归法:
class Solution {
private:
vector<int> vec;
void traversal(TreeNode* root) {
if (root == NULL) return;
traversal(root->left);
vec.push_back(root->val); // 将二叉搜索树转换为有序数组
traversal(root->right);
}
public:
bool isValidBST(TreeNode* root) {
vec.clear(); // 不加这句在leetcode上也可以过,但最好加上
traversal(root);
for (int i = 1; i < vec.size(); i++) {
// 注意要小于等于,搜索树里不能有相同元素
if (vec[i] <= vec[i - 1]) return false;
}
return true;
}
};