Leetcode 235. 二叉搜索树的最近公共祖先
思路分析:
二叉搜索树是二叉树的特例,因此本题也可采用236. 二叉树的最近公共祖先相同的解法,leetcode上也能通过测试。只是没利用二叉搜索树中序遍历有序的特征,不是最优解。
如果root->val比p->val和q->val都大,则说明最近公共祖先一定在root的左子树中。反之,root->val比p->val和q->val都小,则说明最近公共祖先一定在root的左子树中。如果上述2条件都不满足,则返回root。
代码实现:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root->val > p->val && root->val > q->val) {
return lowestCommonAncestor(root->left, p, q);
} else if (root->val < p->val && root->val < q->val) {
return lowestCommonAncestor(root->right, p, q);
} else return root;
}
};
Leetcode 701.二叉搜索树中的插入操作
思路分析:
题意虽然说可能存在多种有效的插入方式,实际上并需要给出所有可能结果,只需给出一种答案就行。根据二叉搜索树中序遍历有序的特征,可以根据root->val与val的关系确定递归顺序,而且顺序是唯一确定的。只要按照二叉搜索树的规则去遍历,遇到空节点就插入节点。
此解法递归是带有返回值的,可以实现遍历到空节点,完成插入操作后,直接用返回值(root->left和root->right)接住返回值,直接完成新二叉搜索树的构建。如果不使用带返回值的递归,则需要专门定义parent节点,插入也需要操作parent.
代码实现:
class Solution {
public:
TreeNode* insertIntoBST(TreeNode* root, int val) {
if (!root) {
TreeNode* node = new TreeNode(val);
return node;
}
if (root->val > val) root->left = insertIntoBST(root->left, val);
if (root->val < val) root->right = insertIntoBST(root->right, val);
return root;
}
};
Leetcode 450.删除二叉搜索树中的节点
思路分析:
删除值为key的节点也要遍历二叉搜索树,可以根据root->val与key的关系决定遍历顺序,同时用root->left或root->right接住递归返回值。单层逻辑里,如果root->left为空,则用非空的root->right节点替换root节点,如果root->right为空,则用非空的root->left节点替换root节点。同时为防止因指针指向变化导致的内存泄漏问题,需要delete root。
如果单层逻辑里root->left和root->right都不为空,则找到右子树中最小的节点作为当前节点的替换节点,将其值赋给当前节点,然后在右子树中递归删除这个最小节点。见方法1. 当然,也可以找到左子树中最大的节点作为当前节点的替换节点,将其值赋给当前节点,然后在左子树中递归删除这个最大节点。见方法2.
代码实现:
找到值为key的节点,并从右子树中移动最小值替代该节点
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (!root) return nullptr;
if (root->val > key) {
root->left = deleteNode(root->left, key);
} else if (root->val < key) {
root->right = deleteNode(root->right, key);
} else {
if (!root->left) {
TreeNode* temp = root->right;
delete root;
return temp;
} else if (!root->right) {
TreeNode* temp = root->left;
delete root;
return temp;
}
TreeNode* temp = root->right;
while (temp->left) {
temp = temp->left;
}
root->val = temp->val;
root->right = deleteNode(root->right, temp->val);
}
return root;
}
};
找到值为key的节点,并从左子树中移动最大值替代该节点
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (!root) return nullptr;
if (root->val > key) {
root->left = deleteNode(root->left, key);
} else if (root->val < key) {
root->right = deleteNode(root->right, key);
} else {
if (!root->left || !root->right) {
TreeNode* temp = root->left ? root->left : root->right;
delete root;
return temp;
}
TreeNode* temp = root->left;
while (temp->right) {
temp = temp->right;
}
root->val = temp->val;
root->left = deleteNode(root->left, temp->val);
}
return root;
}
};