235. 二叉搜索树的最近公共祖先
二叉树的特性是有序==可以依照数值判断节点在哪里
如果根节点为空,就证明没找到,返回空
缩小范围,找到最近的公共祖先,判断两个指定节点的值是否同时大于/小于子树的值
不能缩小范围,就证明已经找到了最近的
class Solution {
public:
TreeNode* transfer(TreeNode* cur, TreeNode* p, TreeNode* q){
if(cur==nullptr) return nullptr;
if(p->val<cur->val&&q->val<cur->val){
TreeNode*leftree= transfer(cur->left,p,q);
if(leftree!=nullptr){
return leftree;
}
}
if(p->val>cur->val&&q->val>cur->val){
TreeNode*rightree= transfer(cur->right,p,q);
if(rightree!=nullptr){
return rightree;
}
}
return cur;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
return transfer(root,p,q);
}
};
因为有序,所以更简单
被迭代法感动得痛哭流涕
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
while(root){
if(p->val>root->val&&q->val>root->val){
root=root->right;
}else if(p->val<root->val&&q->val<root->val){
root=root->left;
}else {
return root;
}
}
return NULL;
}
};
下面这两题让我想起来了当初学二叉搜索树调整的日子
┭┮﹏┭┮
701.二叉搜索树中的插入操作
就是在二叉树中找到合适的位置。和二叉树遍历差不多哦。
递归
class Solution {
public:
//递归,递归的作用是什么?
//为了找到位置
//终止条件是?找到不存在的点
TreeNode* parent;
void transfer(TreeNode* root, int val){
if(root==nullptr){
TreeNode* node=new TreeNode(val);
if(parent->val>val) parent->left=node;
else parent->right=node;
return ;
}
parent=root;
if(root->val>val) {
transfer(root->left, val);
}else{
transfer(root->right,val);
}
return ;
}
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root==nullptr){
TreeNode* node=new TreeNode(val);
return node;
}
parent=root;
transfer(root,val);
return root;
}
};
递归就是把非递归中的while循环部分拆开来写
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
//判断是否为空节点
if(root==nullptr){
TreeNode* node=new TreeNode(val);
return node;
}
TreeNode*parent=root;
TreeNode*cur=parent;
//依照二叉树的特性去向下递归 当前 节点
while(cur!=nullptr){
parent=cur;
if(cur->val>val) cur=cur->left;
else cur=cur->right;
}
//找到相应位置,需要 双亲节点 去指引
TreeNode* node=new TreeNode(val);
if(parent->val>val) parent->left=node;
else parent->right=node;
return root;
}
};
450.删除二叉搜索树中的节点
注意点:
1、每种条件都代表一个情况所以只要删除就返回
2、删除正在访问的节点,递归返回值连接上双亲结点
3、删除的五种情况,五种返回值
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root==nullptr){
return root;
}
//为什么每一个接口都要有返回值?因为找到了就返回
//符合值
if(root->val==key){
if(root->left==nullptr&&root->right==nullptr){
delete root;
return nullptr;
}
if(root->left==nullptr&&root->right!=nullptr){
TreeNode*cur=root;
root=root->right;
delete cur;
return root;
}
if(root->left!=nullptr&&root->right==nullptr){
TreeNode*cur=root;
root=root->left;
delete cur;
return root;
}
if(root->left!=nullptr&&root->right!=nullptr){
//删除节点
TreeNode*denode=root;
//寻找节点
TreeNode*cur=root->right;
//找二叉树右子树的最左节点
while(cur->left!=nullptr){
cur=cur->left;
}
cur->left=root->left;
root=root->right;
delete denode;
return root;
}
}
//不符合值
if((root->val)>key) root->left=deleteNode(root->left,key);
if((root->val)<key) root->right=deleteNode(root->right,key);
return root;
}
};