刷题日记19
今天还是二叉搜索树,二叉搜索树的题型相对还算简单的,要用上二叉搜索树的特点:有序。难点还是递归遍历和逻辑。
235. 二叉搜索树的最近公共祖先
这道题的逻辑大致和[236]相同,区别是这道题是二叉搜索树,如下是二叉树找公共祖先的算法
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if(left == null && right == null) return null;
if(left == null) return right;
if(right == null) return left;
return root;
}
}
二叉搜索树是有序的,那么公共祖先已一定在[p, q]区间或者[q, p]区间内,而在这个区间内的数是不是一定是最近的公共祖先呢?
是!所以我们不需要遍历整个树,找到这个节点就立刻返回,算法如下
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);
if (root.val < p.val && root.val < q.val) return lowestCommonAncestor(root.right, p, q);
return root;
}
}
701. 二叉搜索树中的插入操作
挺简单的题,不需要重构二叉搜索树,只要见缝插针就好
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
if(root == null) return new TreeNode(val);
TreeNode cur = root;
traversal(cur, val);
return root;
}
public void traversal(TreeNode root, int val){
if(root == null) return;
if(root.val < val) traversal(root.right, val);
if(root.val > val) traversal(root.left, val);
TreeNode node = new TreeNode(val);
if(root.val < val && root.right == null) root.right = node;
if(root.val > val && root.left == null) root.left = node;
return;
}
}
450. 删除二叉搜索树中的节点
在二叉搜索树中删除节点要比添加节点困难一些,主要是对树结构的修改,依然是遍历二叉搜索树(不用遍历全树),找到了要被删除的节点后,分为4种情况
- 找到了 为叶子结点
- 找到了 左子树为空
- 找到了 右子树为空
- 找到了 左右子树都不为空
复杂的是第4种,我们要将这个节点的左子树移植到这个节点的右子树的最左边,使整个树保持二叉搜索树的性质
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return root;
if(root.val == key){
// 1. 找到了 为叶子结点
if(root.left == null && root.right == null){
return null;
}
// 2. 找到了 左子树为空
else if(root.left == null){
return root.right;
}
// 3. 找到了 右子树为空
else if(root.right == null){
return root.left;
}
// 4. 找到了 左右子树都不为空
else{
TreeNode right = root.right;
TreeNode left = root.left;
while(right.left != null){
right = right.left;
}
right.left = left;
return root.right;
}
}
if(root.val > key) root.left = deleteNode(root.left, key);
if(root.val < key) root.right = deleteNode(root.right, key);
return root;
}
}