Day22
235.二叉搜索树的最近公共祖先
利用二叉搜索树的有序性,从根节点开始,第一次搜到位于这俩值之间的节点就是最近公共祖先
递归法:
class Solution {
public:
TreeNode* travelsal(TreeNode* node,TreeNode* p,TreeNode* q){
if(node==NULL) return NULL;
if(node->val>p->val && node->val>q->val){
TreeNode* left=travelsal(node->left,p,q);
if(left!=NULL) return left;
}
if(node->val<p->val && node->val<q->val){
TreeNode* right=travelsal(node->right,p,q);
if(right!=NULL) return right;
}
return node;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL) return NULL;
return travelsal(root,p,q);
}
};
迭代法:
对于迭代法,如果把这两个判断用两个while来写,会造成无法识别左右左的情况, 拐不了弯,比如第一个cur -> val 就小于 p q 的话直接就会来到第二个while,以后就不能左拐了
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
while(root){
if(root->val>q->val && root->val > p->val){
root=root->left;
}
else if(root->val < q->val && root->val<p->val){
root=root->right;
}
else return root;
}
return NULL;
}
};
对于需要两个while循环搞定的,试着看能不能只用一个,然后在循环内部使用判断语句。
701.二叉搜索树中的插入操作
递归法:
利用返回值构建父子节点关系
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root == NULL){
TreeNode* node =new TreeNode(val);
return node;
}
if(val > root->val) root->right = insertIntoBST(root->right,val);
if(val < root->val) root->left =insertIntoBST(root->left,val);
return root;
}
};
正常递归法
class Solution {
public:
TreeNode* parent;
void travelsal(TreeNode* cur,int val){
if(cur==NULL){
TreeNode* node = new TreeNode(val);
if(val>parent->val){
parent->right=node;
}
else{
parent->left=node;
}
return;
}
parent=cur;
if(cur->val>val) travelsal(cur->left,val);
if(cur->val<val) travelsal(cur->right,val);
return;
}
TreeNode* insertIntoBST(TreeNode* root, int val) {
parent=new TreeNode(0);
if(root==NULL){
root=parent;
parent->val=val;
return root;
}
travelsal(root,val);
return root;
}
};
迭代法
个人感觉迭代的重点在于不用递归遍历整个树得到结果。
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if(root==NULL){
TreeNode* node=new TreeNode(val);
return node;
}
TreeNode* cur=root;
TreeNode* parent=cur;
while(cur!=NULL){
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 删除二叉搜索树中的节点
迭代法:重点是只有一个节点时的处理情况,这里又分为这个节点就是要找的key和不是要找的key两种情况。
class Solution {
public:
TreeNode* delete1(TreeNode* cur){
if(cur==nullptr) return nullptr;
TreeNode* node=cur;
if(cur->right){
node=cur->right;
while(node->left){
node=node->left;
}
node->left=cur->left;
return cur->right;
}
return cur->left;
}
TreeNode* deleteNode(TreeNode* root, int key) {
if(root== nullptr){
return root;
}
TreeNode* node=root;
TreeNode* parent=nullptr;
while(node){
if(node->val==key) break;
parent=node;
if(node->val>key){
node=node->left;
}
else{
node=node->right;
}
}
if(parent==nullptr) return delete1(node);
if(parent->left&&parent->left->val==key){
parent->left=delete1(node);
}
if(parent->right&&parent->right->val==key){
parent->right=delete1(node);
}
return root;
}
};
递归法
使用了上面说过的使用返回值来处理父子节点。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root==NULL){ return root;}
if(root->val==key){
if(!root->left&&!root->right){
delete root;
return nullptr;
}
else if(!root->left){
auto retnode=root->right;
delete root;
return retnode;
}
else if(root->right==nullptr){
auto retnode=root->left;
delete root;
return retnode;
}
else{
TreeNode* cur=root->right;
while(cur->left){
cur=cur->left;
}
cur->left=root->left;
auto retnode=root->right;
delete root;
return retnode;
}
}
if(root->val > key) root->left=deleteNode(root->left,key);
if(root->val < key) root->right = deleteNode(root->right,key);
return root;
}
};