LeetCode654 最大二叉树
题目链接:最大二叉树
思路
构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
本题共分为三步:
-
先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组;
-
最大值所在的下标左区间构造左子树
- 最大值所在的下标右区间构造右子树
代码
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());
}
};
复杂度
时间复杂度:O(n^2)
空间复杂度:O(n)
Leetcode617 合并二叉树
题目链接:合并二叉树
思路
使用前序遍历,两个二叉树的对应节点可能存在以下三种情况,对于每种情况使用不同的合并方式:
- 如果两个二叉树的对应节点都为空,则合并后的二叉树的对应节点也为空;
- 如果两个二叉树的对应节点只有一个为空,则合并后的二叉树的对应节点为其中的非空节点;
- 如果两个二叉树的对应节点都不为空,则合并后的二叉树的对应节点的值为两个二叉树的对应节点的值之和,此时需要显性合并两个节点。
对一个节点进行合并之后,还要对该节点的左右子树分别进行合并。
代码
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;
}
};
复杂度
时间复杂度:O(min(m,n))
空间复杂度:O(min(m,n)),其中m,n为两棵树的节点数
Leetcode700 最大二叉树中的搜索
题目链接:二叉搜索树中的搜索
思路
根据二叉搜索树的性质(左<中<右)进行分支递归即可。
代码
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if (root == NULL || root->val == val)
return root;
TreeNode* result = NULL;
if (root->val > val)
result = searchBST(root->left, val);
if (root->val < val)
result = searchBST(root->right, val);
return result;
}
};
复杂度
时间复杂度:O(n)
空间复杂度:O(n)
Leetcode98 验证二叉搜索树
题目链接:验证二叉搜索树
思路
只需知道中序遍历下二叉搜索树是有序序列,根据该特性进行判断。
代码
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;
}
};
复杂度
时间复杂度:O(n)
空间复杂度:O(n)