代码随想录刷题随记17-二叉树6
654.最大二叉树
leetcode链接
递归解题思路和之前使用中序后序构建树的思路是一样的
class Solution {
public:
TreeNode * sub(vector<int>& nums,int start,int end){
int index=start;
//int max=nums[start];
for(int i=start;i<=end;i++){
if(nums[i]>nums[index])
index=i;
}
TreeNode * root=new TreeNode (nums[index]);
int numleft=index-start;
if(numleft>0)
root->left=sub(nums,start,index-1);
int numright=end-index;
if(numright>0)
root->right=sub(nums,index+1,end);
return root;
}
TreeNode* constructMaximumBinaryTree(vector<int>& nums) {
if(nums.size()==0)
return nullptr;
return sub(nums,0,nums.size()-1);
}
};
617.合并二叉树
leetcode链接
本质上是二叉树的遍历
解题代码:
class Solution {
public:
TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
if(root1==nullptr)
return root2;
if(root2==nullptr)
return root1;
TreeNode * root=new TreeNode(root1->val+root2->val);
root->left=mergeTrees(root1->left,root2->left);
root->right=mergeTrees(root1->right,root2->right);
return root;
}
};
700.二叉搜索树中的搜索
leetcode链接
二叉搜索树是一个有序树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉搜索树
递归:
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root==nullptr)
return nullptr;
if(val==root->val)
return root;
if(val<root->val)
return searchBST(root->left,val);
else
return searchBST(root->right,val);
}
};
迭代:有点类似链表的遍历
class Solution {
public:
TreeNode* searchBST(TreeNode* root, int val) {
if(root==nullptr)
return nullptr;
TreeNode* cur=root;
while(cur!=nullptr){
if(cur->val==val)
return cur;
if(cur->val>val)
cur=cur->left;
else
cur=cur->right;
}
return nullptr;
}
};
98.验证二叉搜索树
这道题目比较容易陷入两个陷阱:
陷阱1
不能单纯的比较左节点小于中间节点,右节点大于中间节点就完事了。
我们要比较的是 左子树所有节点小于中间节点,右子树所有节点大于中间节点。
所以这样的解法是错误的:
陷阱2
溢出的问题
class Solution {
public:
bool sub(TreeNode* root ){
if(root==nullptr)
return true;
bool ju1=true;
bool ju2=true;
if(root->left!=nullptr)
ju1=root->left->val<root->val;
if(root->right!=nullptr)
ju2=root->right->val>root->val;
bool ju3=sub(root->left);
bool ju4=sub(root->right);
return ju1&&ju2&&ju3&&ju4;
}
bool isValidBST(TreeNode* root) {
return sub(root);
}
};
所以递归必须记录最大最小信息
解题代码:
class Solution {
public:
struct info {
public:
long long minn;
long long maxx;
info():minn(LONG_LONG_MAX),maxx(LONG_LONG_MIN){
}
};
bool sub(TreeNode* root ,info& info ){
if(root==nullptr)
return true;
bool ju1=true;
bool ju2=true;
struct info info1;
struct info info2;
bool ju3=sub(root->left,info1);
if(info1.maxx>=root->val)
ju1=false;
bool ju4=sub(root->right,info2);
if(info2.minn<=root->val)
ju2=false;
info.maxx=info2.maxx>root->val?info2.maxx:root->val;
info.minn=info1.minn<root->val?info1.minn:root->val;
return ju1&&ju2&&ju3&&ju4;
}
bool isValidBST(TreeNode* root) {
struct info info3;
return sub(root,info3);
}
};
迭代法
要知道中序遍历下,输出的二叉搜索树节点的数值是有序序列。
有了这个特性,验证二叉搜索树,就相当于变成了判断一个序列是不是递增的了
迭代法中序遍历稍加改动就可以了:
解题代码:
class Solution {
public:
bool isValidBST(TreeNode* root) {
if(root==nullptr)
return true;
stack<TreeNode *> mystack;
//mystack.push(root);
TreeNode * cur=root;
TreeNode *pre=nullptr;
while(!mystack.empty()||cur!=nullptr){
if(cur!=nullptr){
mystack.push(cur);
cur=cur->left;
}
else{
cur=mystack.top();
mystack.pop();
if(pre!=nullptr&&cur->val<=pre->val)
return false;
pre=cur;//保存前一个访问的节点
cur=cur->right;
}
}
return true;
}
};