leetcode 654.最大二叉树
题目链接:654. 最大二叉树 - 力扣(LeetCode)
视频链接:又是构造二叉树,又有很多坑!| LeetCode:654.最大二叉树_哔哩哔哩_bilibili
题目概述:
给定一个不重复的整数数组构建最大二叉树,构建规则如下:
1.根节点是最大值。
2.在最大值左边的数用来构建左子树。
3.在最大值右边的数用来构建右子树。
示例 1:
输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,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 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> newVec(nums.begin(), nums.begin() + maxValueIndex);
node->left = constructMaximumBinaryTree(newVec);
}
if (maxValueIndex < (nums.size() - 1)) {
vector<int> newVec(nums.begin() + maxValueIndex + 1, nums.end());
node->right = constructMaximumBinaryTree(newVec);
}
return node;
}
};
leetcode 617.合并二叉树
题目链接:617. 合并二叉树 - 力扣(LeetCode)
视频链接:一起操作两个二叉树?有点懵!| LeetCode:617.合并二叉树_哔哩哔哩_bilibili
题目概述:
给你两棵二叉树:
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会),如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值,否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
示例 1:
输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]
·注意: 合并过程必须从两个树的根节点开始。
思路
本题其实用哪种遍历方式都行(前中后都可以)。我们可以不用去定义一个新的树,用给的树1就可以,在树1的基础上加树2,这样最后就会变成一个合并好的新树,定义一个新的树也行,只不过会多加那么一丢丢代码。以前序为例,合并二叉树的过程,如图所示:
代码实现
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
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;
}
};
leetcode 700.二叉搜索树中的搜索
题目链接:700. 二叉搜索树中的搜索 - 力扣(LeetCode)
视频链接:不愧是搜索树,这次搜索有方向了!| LeetCode:700.二叉搜索树中的搜索_哔哩哔哩_bilibili
题目概述:
给定二叉搜索树(BST)的根节点 root 和一个整数值 val。
你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。
示例 1:
输入:root = [4,2,7,1,3], val = 2 输出:[2,1,3]
思路
做这道题之前,我们要知道什么是二叉搜索树,二叉搜索树满足它的根节点要比左子树里所有数都大,比右子树里所有数都小,当然了这在左右子树里依旧符合这个规则。所以说这道题不用去考虑顺序问题,因为二叉搜索树本身已经给了我们顺序。也正是因为二叉搜索树的有序性,也会使代码变得出乎意外的简单。
代码实现
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root == NULL || root->val == val) return root;
if(val < root->val) return searchBST(root->left,val);
if(val > root->val) return searchBST(root->right,val);
return NULL;
}
};
leetcode 98.验证二叉搜索树
题目链接:98. 验证二叉搜索树 - 力扣(LeetCode)
视频链接:你对二叉搜索树了解的还不够! | LeetCode:98.验证二叉搜索树_哔哩哔哩_bilibili
题目概述:
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
思路
验证二叉搜索树最直白的想法就是把这棵树变成一个数组,然后比较大小,要注意的是二叉搜索树中元素不能有重复的。这道题还需要注意的是不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。如图所示:
·这就不是棵二叉搜索树了! !
其实本题也可以用双指针法来进行优化(可以避免初始化最小值),定义一个指针,用它来记录前一个结点,然后比大小就行了。
代码实现
要知道根节点是空的话,它既是二叉搜索树,也是平衡二叉树,它啥树都是。
class Solution {
public:
TreeNode* pre = NULL; // 用来记录前一个节点
bool isValidBST(TreeNode* root) {
if (root == NULL) return true;
bool left = isValidBST(root->left);
if (pre != NULL && pre->val >= root->val) return false;
pre = root; // 记录前一个节点
bool right = isValidBST(root->right);
return left && right;
}
};