提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
今天是跟着代码随想录训练营刷题的第20天,今天主要学习了654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树这四个内容
链接地址:最大二叉树、合并二叉树、二叉搜索树中的搜索、验证二叉搜索树。
提示:以下是本篇文章正文内容,下面案例可供参考
一、654.最大二叉树
思路:这道题就是给你一个数组,让你按照里面最大的树为根,左子树和右子树同理。所以先找到数组里面最大的当做根节点,把左右分成两个数组,然后左边和右边再迭代,相同的方法再找最大的当根节点。
代码:
class Solution {
public:
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size()==0) return NULL;
int index=0;
int maxvalue=nums[0];
int i=0;
for(;i<nums.size();i++)
{
if(nums[i]>maxvalue)
{
maxvalue=nums[i];
index=i;
}
}
TreeNode* root=new TreeNode(maxvalue);
vector<int> left(nums.begin(),nums.begin()+index);
vector<int> right(nums.begin()+index+1,nums.end());
root->left=constructMaximumBinaryTree(left);
root->right=constructMaximumBinaryTree(right);
return root;
}
};
二、合并二叉树
思路:如果root1的左边空的,就返回右边,如果root1的右边空的就返回左边,然后如果都不空,就返回两个的值之和就好了,然后左边右边分别用递归。
代码:
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1==NULL) return root2;
if(root2==NULL) return root1;
TreeNode* root=new TreeNode(0);
root->val=root1->val+root2->val;
root->left=mergeTrees(root1->left,root2->left);
root->right=mergeTrees(root1->right,root2->right);
return root;
}
};
三、二叉搜索树中的搜索
迭代法思路:很简单,就是对比这个节点的值和目标值哪个大,因为是二叉搜索树,数值大小是比较有规律的。当然前提是节点不为空。
迭代法代码:
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 break;
}
return root;
}
};
递归法思路:同样在节点不为空的情况下,如果相等了就返回root,如果不相等,大了小了分别调用递归就行了。
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;
}
};
四、验证二叉搜索树
二叉搜索树其实就是根节点大于左子树又要大于右子树,注意是大于左子树的全部,并不是大于左节点就可以了,一种直接的方法就是把二叉树进行一个遍历写成一个数组的形式,然后判断数组是不是单调递增的就可以了,但是这种方法比较麻烦,我们看到二叉搜索树要想到中序遍历,我们可以在中序遍历的迭代中判断就好了,最好的还是用双指针,后面比较前面的更加方便
双节点法:
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;
}
};
这里注意节点要定义在最前面,不然每经历一次递归,节点都变成NULL了
暴力解法:
class Solution {
public:
void faker(TreeNode* root,vector<int>& result)
{
if(root==NULL) return;
faker(root->left,result);
result.push_back(root->val);
faker(root->right,result);
}
bool isValidBST(TreeNode* root) {
vector<int> result;
faker(root,result);
if(result.size()>1)
{
for(int i=0,j=1;i<result.size()-1;i++,j++)
{
if(result[j]>result[i]) continue;
else return false;
}
return true;
}
else return true;
}
};
这里注意vector& result不能用值传递,因为值传递不改变本身result的值,只有用引用传递才能把函数中的修改反映到result上。