654.最大二叉树
链接:
https://leetcode.cn/problems/maximum-binary-tree/
思路:
构造树一般采用的是前序遍历,因为先构造中间节点,然后递归构造左子树和右子树。
- 确定递归函数的参数和返回值
参数传入的是存放元素的数组,返回该数组构造的二叉树的头结点,返回类型是指向节点的指针。
- 确定终止条件
题目中说了输入的数组大小一定是大于等于1的,所以我们不用考虑小于1的情况,那么当递归遍历的时候,如果传入的数组大小为1,说明遍历到了叶子节点了。
那么应该定义一个新的节点,并把这个数组的数值赋给新的节点,然后返回这个节点。 这表示一个数组大小是1的时候,构造了一个新的节点,并返回。
- 确定单层递归的逻辑
这里有三步工作
1.先要找到数组中最大的值和对应的下标, 最大的值构造根节点,下标用来下一步分割数组。
2.最大值所在的下标左区间 构造左子树
这里要判断maxValueIndex > 0,因为要保证左区间至少有一个数值。
3.最大值所在的下标右区间 构造右子树
判断maxValueIndex < (nums.size() - 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;
}
};
合并二叉树
链接:
https://leetcode.cn/problems/merge-two-binary-trees/
思路:
如果树1为空,返回树2,如果树2为空,返回树1.
如果都不为空,则树1 += 树2
返回的节点为树1
然后递归的执行此逻辑
题解:
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;
}
};
700.二叉搜索树中的搜索
链接:
https://leetcode.cn/problems/search-in-a-binary-search-tree/
思路:
如果当前遍历的节点为空 或者 当前的节点的值等于 目标值,则返回当前节点
如果当前遍历的节点大于 目标值,则递归的向左遍历
如果当前遍历的节点小于 目标值,则递归的向右遍历
手法:
如果返回值相同,但是条件不同,可以将条件合并为 或语句
if(root==NULL || root->val == val)
{ return root; }
题解:
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
while(root!=NULL)
{
if(root->val == val) return root;
else if(root->val > val ) root=root->left;
else if(root->val < val) root= root ->right;
}
return NULL;
}
};
迭代法:
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
while(root!=NULL)
{
if(root->val == val) return root;
else if(root->val > val ) root=root->left;
else if(root->val < val) root= root ->right;
}
return NULL;
}
};
98.验证二叉搜索树
链接:
https://leetcode.cn/problems/validate-binary-search-tree/
思路:
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了。
手法:
1.在二叉搜索树中,如果要判断是否为二叉搜索树,则可以定义一个 类的成员变量指针,指向前一个节点
2.写好一个条件后,如果发现这个条件在 某种情况A下 不满足,则 在 条件判断 之前 用 && 排除掉 某种情况A
if (pre != NULL && pre->val >= root->val) return false;
题解:
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;
}
};