算法刷题记录 Day19
Date: 2024.03.13
lc 450. 删除二叉搜索树中的结点
// 递归。优势在于无需记录pre结点,只需在返回时不返回要删除的结点即可。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
// 1.遍历结束,没找到对应结点
if(root == nullptr) return nullptr;
if(root->val == key){
// 1.是叶子结点,删除
if(!root->left && !root->right){
return nullptr;
}
// 2.只有一个子树
else if(!root->left){
return root->right;
}
else if(!root->right){
return root->left;
}
//3. 左右子树都存在,将左子树挪到右子树的最左结点
else{
TreeNode* left = root->left;
TreeNode* right = root->right;
while(right->left){
right = right->left;
}
right->left = left;
TreeNode* new_node = root->right;
return new_node;
}
}
root->left = deleteNode(root->left, key);
root->right = deleteNode(root->right, key);
return root;
}
};
// 迭代
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(root == nullptr) return root;
TreeNode* pre = nullptr;
TreeNode* tmp = root;
while(tmp){
if(tmp->val == key){ //找到需删除结点
//1. 叶子结点
if(!tmp->left && !tmp->right){
if(!pre){
return nullptr;
}
else{
if(pre->left == tmp) pre->left = nullptr;
else pre->right = nullptr;
}
}
//2. 只有一个孩子结点
else if(!tmp->left||!tmp->right){
if(pre){
if(tmp->left){
if(pre->left == tmp) pre->left = tmp->left;
else pre->right = tmp->left;
}
else{
if(pre->left == tmp) pre->left = tmp->right;
else pre->right = tmp->right;
}
}
else{
if(tmp->left){
return tmp->left;
}
else
return tmp->right;
}
}
//3. 有两个孩子结点,则将删除结点的左子树放到其右孩子结点的最左结点上,
// 并用其右孩子结点替代要删除的结点。
else{
TreeNode* delete_left = tmp->left;
TreeNode* delete_right = tmp->right;
while(delete_right->left){
delete_right = delete_right->left;
}
delete_right->left = delete_left;
TreeNode* new_node = tmp->right;
if(pre){
if(pre->left == tmp) pre->left = new_node;
else pre->right = new_node;
}
else{
return new_node;
}
}
break;
}
else{
if(key > tmp->val){
pre = tmp;
tmp = tmp->right;
}
else{
pre = tmp;
tmp = tmp->left;
}
}
}
return root;
}
};
lc 235. 二叉搜索树的最近公共祖先
class Solution {
public:
// 自顶向下搜索,遇到的第一个在区间[p,q]内的节点就是最近公共祖先。
TreeNode* lowestCommonAncestor(TreeNode* node, TreeNode* p, TreeNode* q) {
if(!node) return nullptr;
while(node){
if(node->val > p->val && node->val > q->val){
node = node->left;
}
else if(node->val < p->val && node->val < q->val){
node = node->right;
}
else{
return node;
}
}
return nullptr;
}
};
lc 701. 二叉搜索树中的插入
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
TreeNode* new_node = new TreeNode(val);
if(root == nullptr) return new_node;
TreeNode* tmp = root;
while(tmp){
if(!tmp->left && !tmp->right){ //叶子节点
if(tmp->val > val){
tmp->left = new_node;
break;
}
else{
tmp->right = new_node;
break;
}
}
else if(tmp->left && tmp->right){ //两侧非空
if(tmp->val > val)
tmp = tmp->left;
else
tmp = tmp->right;
}
else{ //单侧节点
if(tmp->left){
if(tmp->val > val) tmp = tmp->left;
else{
tmp->right = new_node;
break;
}
}
else{
if(tmp->val < val) tmp = tmp->right;
else{
tmp->left = new_node;
break;
}
}
}
}
return root;
}
};