今日任务
- 654.最大二叉树
- 617.合并二叉树
- 700.二叉搜索树中的搜索
- 98.验证二叉搜索树
654.最大二叉树
题目链接:
https://leetcode.cn/problems/maximum-binary-tree/description/
题目描述:
给定一个不重复的整数数组 nums
。 最大二叉树 可以用下面的算法从 nums
递归地构建:
- 创建一个根节点,其值为
nums
中的最大值。 - 递归地在最大值 左边 的 子数组前缀上 构建左子树。
- 递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums
构建的 最大二叉树 。
示例 1:
输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解释:递归调用如下所示:
- [3,2,1,6,0,5] 中的最大值是 6 ,左边部分是 [3,2,1] ,右边部分是 [0,5] 。
- [3,2,1] 中的最大值是 3 ,左边部分是 [] ,右边部分是 [2,1] 。
- 空数组,无子节点。
- [2,1] 中的最大值是 2 ,左边部分是 [] ,右边部分是 [1] 。
- 空数组,无子节点。
- 只有一个元素,所以子节点是一个值为 1 的节点。
- [0,5] 中的最大值是 5 ,左边部分是 [0] ,右边部分是 [] 。
- 只有一个元素,所以子节点是一个值为 0 的节点。
- 空数组,无子节点。
示例 2:
输入:nums = [3,2,1]
输出:[3,null,2,null,1]
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
nums
中的所有整数 互不相同
题解代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//二刷
TreeNode* constructMaximumBinaryTree(vector<int>& nums){
TreeNode* node = new TreeNode(0);
//处理所给数组中只有一个数的情况
if(nums.size() == 1){
node->val = 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;
}
}
node->val = maxValue; //根
//处理左
if(maxValueIndex > 0){
vector<int> leftVec(nums.begin(), nums.begin()+maxValueIndex);//区间:左闭右开
node->left = constructMaximumBinaryTree(leftVec);
}
//处理右
if(maxValueIndex < nums.size()-1){
vector<int> rightVec(nums.begin()+maxValueIndex+1, nums.end()); //区间:左闭右开原则
node->right = constructMaximumBinaryTree(rightVec);
}
return node;
}
//一刷
/*
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
//设计构建二叉树,我们用前序的方式
TreeNode* resNode = new TreeNode(0);
if(nums.size()==1){
resNode->val = nums[0];
return resNode;
}
//处理根
int maxValue = 0; //假定 最大值
int index = 0; // 记录最大值的下标
for(int i = 0; i < nums.size();i++){//遍历数组
if(nums[i]>maxValue){ //如果遇到比我们假定的最大值更大的元素,则更新
maxValue = nums[i];
index = i; //下标也要记得更新
}
}
resNode->val = maxValue;
//处理左
if(index > 0){ //要保证左区间至少有一个元素,才有继续下去的必要
vector<int> leftVec(nums.begin(), nums.begin()+index);//对于区间,我们始终坚持左闭右开的原则
resNode->left = constructMaximumBinaryTree(leftVec); //去递归吧,构建左子树
}
//处理右
if(index < nums.size()-1){// 要保证右区间至少有一个元素,才有继续 下去 的必要
vector<int> rightVec(nums.begin()+index+1, nums.end());//对于区间,我们始终坚持左闭右开的原则
resNode->right = constructMaximumBinaryTree(rightVec); //去递归,构建右子树
}
return resNode;
}
*/
};
617.合并二叉树
题目链接:
https://leetcode.cn/problems/merge-two-binary-trees/description/
题目描述:
给你两棵二叉树: root1
和 root2
。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
示例 1:
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]
示例 2:
输入:root1 = [1], root2 = [1,2]
输出:[2,2]
提示:
- 两棵树中的节点数目在范围
[0, 2000]
内 104 <= Node.val <= 104
题解代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//二刷
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2){
//处理树1为空树的情况
if(root1 == NULL){
return root2;
}
if(root2 == NULL){
return root1;
}
root1->val += root2->val;
root1->left = mergeTrees(root1->left,root2->left);
root1->right = mergeTrees(root1->right,root2->right);
return root1;
}
//一刷,递归法,操作两个树
/*
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
//还是要造树,所以还是用前序
if(root1 == NULL){
return root2;
}
if(root2 == NULL){
return root1;
}
//就在tree1上面做改动,不构建新树了
root1->val += root2->val;
root1->left = mergeTrees(root1->left, root2->left);
root1->right = mergeTrees(root1->right, root2->right);
return root1;
}
*/
};
700.二叉搜索树中的搜索
题目链接:
https://leetcode.cn/problems/search-in-a-binary-search-tree/description/
题目描述:
给定二叉搜索树(BST)的根节点 root
和一个整数值 val
。
你需要在 BST 中找到节点值等于 val
的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null
。
示例 1:
输入:root = [4,2,7,1,3], val = 2
输出:[2,1,3]
示例 2:
输入:root = [4,2,7,1,3], val = 5
输出:[]
提示:
- 数中节点数在
[1, 5000]
范围内 1 <= Node.val <= 107
root
是二叉搜索树1 <= val <= 107
题解代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//二刷
TreeNode* searchBST(TreeNode* root, int val){
//利用二叉搜索树本身特点 递归地搜索val
if(root == NULL || root->val == val){
return root;
}
TreeNode* resNode = NULL;
if(val < root->val){
resNode = searchBST(root->left, val);
}
if(val > root->val){
resNode = searchBST(root->right, val);
}
return resNode;
}
//一刷
/*
TreeNode* searchBST(TreeNode* root, int val) {
//二叉搜索树,左节点值比根节点值小,右比根大
//递归法
//递归终止条件
if(root==NULL || root->val==val){
return root;
}
TreeNode* resNode = NULL;
if(val < root->val){
resNode = searchBST(root->left, val);
}
if(val > root->val){
resNode = searchBST(root->right,val);
}
return resNode;
}
*/
};
98.验证二叉搜索树
题目链接:
https://leetcode.cn/problems/validate-binary-search-tree/description/
题目描述:
给你一个二叉树的根节点 root
,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
- 节点的左子树只包含 小于 当前节点的数。
- 节点的右子树只包含 大于 当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
- 树中节点数目范围在
[1, 104]
内 231 <= Node.val <= 231 - 1
题解代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//二刷: 递归法, 中序遍历
TreeNode* pre = NULL; //记录当前节点地前一个节点
bool isValidBST(TreeNode* root){
if(root == NULL){
return true;
}
bool IsLeft = isValidBST(root->left);//左
//中
if(pre != NULL && pre->val >= root->val){
return false;
}
pre = root;
//右
bool IsRight = isValidBST(root->right);//右
return IsLeft&&IsRight;
}
//一刷:递归法
/*
TreeNode* pre = NULL; //记录当前遍历节点的前一个结点
bool isValidBST(TreeNode* root) {
if(root == NULL){
return true; //空 便可是 万物
}
//二叉搜索树特点:左比根小,右比根大,中序遍历下来恰好是递增序列
//中序
//处理左
bool leftIs = isValidBST(root->left);
//处理中
if(pre!=NULL && pre->val>=root->val){
return false;
}
pre = root;
//处理右
bool rightIs = isValidBST(root->right);
return leftIs&&rightIs;
}
*/
};
总结
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
⇒ 验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。