代码随想录训练营第22天|235. 二叉搜索树的最近公共祖先,701.二叉搜索树中的插入操作,450.删除二叉搜索树中的节点
)
235.二叉搜索树的最近公共祖先
文章
思路
从根节点出发
如果当前节点值介于两目标节点之间,说明目标节点分别在当前节点的左右子树中,则当前节点必然是最近公共祖先
若当前节点小于目标节点值则目标节点在右子树,下一步访问右孩子
若当前节点大于目标节点值则目标节点在左子树,下一步访问左孩子
考虑特殊情况,,目标节点中一个是另一个的祖先,则可以用闭区间确定当前节点而没有例外
代码
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
int upper, lower;
upper = p.val > q.val ? p.val : q.val;
lower = p.val > q.val ? q.val : p.val;
TreeNode node = root;
while(node.val < lower || node.val > upper) {
if (node.val < lower) {
node = node.right;
} else {
node = node.left;
}
}
return node;
}
}
701.二叉搜索树中的插入操作
文章
思路
最简单思路是找到一个可插入的位置,插入新节点
代码
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if (root == null) {
return new TreeNode(val);
}
TreeNode node = root;
while (true) {
if (node.val > val) {
if (node.left == null) {
node.left = new TreeNode(val);
return root;
} else {
node = node.left;
continue;
}
} else {
if (node.right == null) {
node.right = new TreeNode(val);
return root;
} else {
node = node.right;
continue;
}
}
}
// return root;
}
}
450.删除二叉搜索树中的节点
文章
思路
找到删除的目标节点,维护目标节点的父节点,标记目标节点是其父节点的左或右孩子
为了应对删除根节点的情况,建立虚节点,使根节点成为其的一个孩子
找到删除的目标节点后,将目标节点的一个非空孩子插入目标节点的原位置,可以通过父节点和左右标记确定,另一个孩子插入前一个孩子的末端,如果插入父节点的是大孩子,则小孩子插入大孩子的最左,如果插入父节点的是小孩子,则大孩子插入小孩子的右端。
最后返回虚节点的孩子
代码
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if (root == null) {
return null;
}
TreeNode pre;
TreeNode dummy = new TreeNode(-100001);
dummy.right = root;
pre = dummy;
TreeNode node = root;
int child = 1;
while (node != null && node.val != key) {
pre = node;
if (node.val > key) {
node = node.left;
child = 0;
} else {
node = node.right;
child = 1;
}
}
if (node == null) {
return root;
}
TreeNode lower, upper;
lower = node.left;
upper = node.right;
if (child == 0) {
if (upper != null) {
pre.left = upper;
if (lower != null) {
while (upper.left != null) {
upper = upper.left;
}
upper.left = lower;
}
} else {
pre.left = lower;
}
}
else if (child == 1) {
if (lower != null) {
pre.right = lower;
if (upper != null) {
while (lower.right != null) {
lower = lower.right;
}
lower.right = upper;
}
} else {
pre.right = upper;
}
}
return dummy.right;
}
}
总结
总体上比较简单
删除操作比较复杂
虚节点这种做法原来不止适用于链表