leetcode-zgd-day22-235.二叉搜索树的最近公共祖先/701.二叉搜索树中的插入操作/450.删除二叉搜索树中的节点

44 阅读1分钟

235.二叉搜索树的最近公共祖先

题目链接:235. 二叉搜索树的最近公共祖先 - 力扣(LeetCode)

解题思路:

这个写法根本没用到二叉搜索树这个性质,是个树就可以这么写

 class Solution {
     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { // 返回的值是最小的公共节点或者p和q
         // 首先想要找到最近的公共祖先,就一定得自底向上,那么就需要后序遍历 左右中
         if(root == p || root == q || root == null) return root;
         TreeNode left = lowestCommonAncestor(root.left, p, q);
         TreeNode right = lowestCommonAncestor(root.right, p, q);
         if(left != null && right != null){
             return root;
         }
         if(left != null && right == null) return left;
         else if(left == null && right != null) return right;
         else return null;
     }
 }

利用了二叉搜索树的性质:层序遍历,第一个满足val在p和q的val之间的树节点就是最小的公共节点

 class Solution {
     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { // 返回的值是最小的公共节点或者p和q
         // 层序遍历,第一个夹在两种中间的就是最近公共祖先
         Queue<TreeNode> que = new LinkedList<>();
         que.offer(root);
         while(!que.isEmpty()){
             TreeNode cur = que.poll();
             if(((cur.val - p.val) <= 0 && (cur.val - q.val) >= 0)
             || ((cur.val - p.val) >= 0 && (cur.val - q.val) <= 0)){
                 return cur;
             }
             if(cur.left != null) que.offer(cur.left);
             if(cur.right != null) que.offer(cur.right);
         }
         return null;
     }
 }

701.二叉搜索树中的插入操作

题目链接:701. 二叉搜索树中的插入操作 - 力扣(LeetCode)

解题思路:

只是实现了最简单的一种,直接去树里面找他的位置

 class Solution {
     public TreeNode insertIntoBST(TreeNode root, int val) {
         TreeNode node = new TreeNode(val);
         if(root == null) return node;
         TreeNode cur = root;
         while(cur.left != null || cur.right != null){
             if(cur.val < val && cur.right != null){
                 cur = cur.right;
             }else if(cur.val > val && cur.left != null){
                 cur = cur.left;
             }else{
                 break;
             }
         }
         if(cur.val < val){
             cur.right = node;
         }
         else{
             cur.left = node;
         }
         return root;
     }
 }

450.删除二叉搜索树中的节点

题目链接:450. 删除二叉搜索树中的节点 - 力扣(LeetCode)

解题思路:

就是进行了一个模拟

1.首先是判断树里是否有要删除的结点

2.有的话判断是否有左右孩子,根据有没有左右孩子分类进行处理

最复杂的就是左右孩子都有的情况,可以让右孩子顶替要删除结点的位置,然后将要删除结点的左孩子当作要删除结点右孩子中最左侧的结点,也就是右孩子中最小值结点的左孩子。

就是如果要删除结点是root的话需要单独处理,比较麻烦,方法有待改进。

 class Solution {
     public TreeNode deleteNode(TreeNode root, int key) {
         // 将这个题分为两步,第一步找到要删除节点位置,第二步,重构树
         if(root == null) return null;
         if(root.val == key){
             if(root.left == null && root.right == null) return null;
             else if(root.left == null && root.right != null) return root.right;
             else if(root.right == null && root.left != null) return root.left;
             else{
                 TreeNode p = root.right;
                 while(p.left != null){
                     p = p.left;
                 }
                 p.left = root.left;
                 return root.right;
             }
         }
         // 1.找出要删除节点的位置
         TreeNode cur = root;
         TreeNode pre = root;
         int flag = -1; //为0代表当前节点为父节点的左孩子,1代表右孩子
         while(cur.val != key){
             if(cur.val < key && cur.right != null){
                 if(cur.right.val == key){
                     pre = cur;
                     flag = 1;
                 }
                 cur = cur.right;
             }else if(cur.val > key && cur.left != null){
                 if(cur.left.val == key){
                     pre = cur;
                     flag = 0;
                 }
                 cur = cur.left;
             }else{
                 break;
             }
         }
         // 没有value为key的节点
         if(cur.val != key) return root;
         // 找到了 cur就是要删除的节点,将cur.left接到cur.right的最小的节点上 cur.right最小的节点就是一直往左走知道为空
         if(cur.left == null && cur.right == null){//叶子节点,左右孩子都不存在
             if(flag == 1) pre.right = null;
             else if(flag == 0) pre.left = null;
             return root;
         }
         else if(cur.left == null && cur.right != null){
             if(flag == 1) pre.right = cur.right;
             else if(flag == 0) pre.left = cur.right;
             return root;
         }
         else if(cur.left != null && cur.right == null){
             if(flag == 1) pre.right = cur.left;
             else if(flag == 0) pre.left = cur.left;
             return root;
         }
         // 左右都不为空
         TreeNode q = cur.right;
         if(flag == 1) pre.right = q;
         else if(flag == 0) pre.left = q;
         while(q.left != null){
             q = q.left;
         }
         q.left = cur.left;
         return root;
     }
 }