代码随想录算法训练营第二十一天,二十二,二十三| 530. 二叉搜索树的最小绝对差 501. 二叉搜索树中的众数 236. 二叉树的最近公共祖先 235. 二叉搜索树的最近公共祖先 701. 二叉搜索树中的插入操作 450. 删除二叉搜索树中的节点

530. 二叉搜索树的最小绝对差
https://leetcode.cn/problems/minimum-absolute-difference-in-bst/description/

TreeNode pre = null;
    int res = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        if (root == null) return 0;
        preorder(root);
        return res;
    }
    public void preorder(TreeNode node){
        if (node == null) return;
        preorder(node.left);
        if (pre != null){
            res = Math.min(res,node.val - pre.val);
        }
        pre = node;
        preorder(node.right);
    }

总结:二叉搜索树的中序就是从小到大排序,每次中序的过程中记录下来上一个节点,每次计算当前值和上一个值的差,注:处理完自己的逻辑再令pre=自己,就是给下一个节点指定了pre
501. 二叉搜索树中的众数
https://leetcode.cn/problems/find-mode-in-binary-search-tree/description/

TreeNode pre = null;
    int maxcount = 0;
    int curcount = 0;
    List<Integer> res = new ArrayList<>();
    public int[] findMode(TreeNode root) {
        preorder(root);
        int[] res1 = new int[res.size()];
        for (int i = 0; i < res.size(); i++) {
            res1[i] = res.get(i);
        }
        return res1;
    }
    public void preorder(TreeNode node){
        if (node == null) return;
        preorder(node.left);
        if (pre == null || pre.val != node.val){
            curcount = 1;
        }else {
            curcount++;
        }
        if (curcount > maxcount){
            res.clear();
            res.add(node.val);
            maxcount = curcount;
        }else if (curcount == maxcount){
            res.add(node.val);
        }
        pre = node;
        preorder(node.right);
    }

总结:由于是二叉搜索树,中序遍历是有序的,所以相同的节点分类,如果是第一个i点就置curcount为1,不是第一个就直接++,加完了之后看curcount如果等于maxcount了就直接进res,如果大于了就清空res再进res。 这个方法要保存pre为前置节点。
236. 二叉树的最近公共祖先
https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/description/

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) { // 若未找到节点 p 或 q
            return null;
        }else if(left == null && right != null) { // 若找到一个节点
            return right;
        }else if(left != null && right == null) { // 若找到一个节点
            return left;
        }else { // 若找到两个节点
            return root;
        }
    }

总结:首先一定是后序,每次从根去看左右子树,返回的节点是左右子树中找到的是p还是q还是什么都没有,再对这三者进行判断,找到了最小公共祖先之后就返回这个点,一直返回这个点没否则就返回单左或单右。 由于题中默认一定有祖先,所以如果发生q是p的孩子的情况,直接遍历到p的时候返回p就好,不用管p下面还有没有q,因为最后如果q在p下面,返回p没毛病,如果q不在p下面,返回p更没毛病。
235. 二叉搜索树的最近公共祖先
https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/description/

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;
    }

总结:还是题中默认p,q一定有祖先,所以当遍历到一个点 p,q在不同的子树中时,这个点就是最小祖先。
701. 二叉搜索树中的插入操作
https://leetcode.cn/problems/insert-into-a-binary-search-tree/description/

public TreeNode insertIntoBST(TreeNode root, int val) {
        if (root == null) return new TreeNode(val);
        insertHelper(root,val);
        return root;
    }
    public void insertHelper(TreeNode node,int val){
        if (val < node.val){
            if (node.left != null){
                insertHelper(node.left,val);
            }else {
                node.left = new TreeNode(val);
            }
        }else {
            if (node.right != null){
                insertHelper(node.right,val);
            }else {
                node.right = new TreeNode(val);
            }
        }
    }

总结:我没有考虑转换树形结构的问题,我只是找到位置然后插入,前序遍历,看当前节点如果 val应该在node左边且node的left还为null,就插进去,这种遍历。
450. 删除二叉搜索树中的节点
https://leetcode.cn/problems/delete-node-in-a-bst/description/

public TreeNode deleteNode(TreeNode root, int key) {
        if (root == null) return null;
        if (root.val == key){
            if (root.left == null){
                return root.right;
            }else if (root.right == null){
                return root.left;
            }else {
                TreeNode cur = root.right;
                while (cur.left != null){
                    cur = cur.left;
                }
                cur.left = root.left;
                root = root.right;
                return root;
            }
        }
        if (root.val > key) root.left = deleteNode(root.left,key);
        if (root.val < key) root.right = deleteNode(root.right,key);
        return root;
    }

总结:二叉搜索树的删除在于 如果删除的点没有左右孩子,直接返回null,有左没右,返回左,有右没左,返回右,左右都有,把要删的点的左子树的根放到右子树的最左节点的左边(题目关键在这)
669. 修剪二叉搜索树
https://leetcode.cn/problems/trim-a-binary-search-tree/description/

public TreeNode trimBST(TreeNode root, int low, int high) {
        if (root == null) return null;
        if (root.val < low){
            return trimBST(root.right,low,high);
        }
        if (root.val > high){
            return trimBST(root.left,low,high);
        }
        root.left = trimBST(root.left,low,high);
        root.right = trimBST(root.right,low,high);
        return root;
    }

总结:前序遍历,如果节点值比low还小,就返回右子树替代自己,如果节点值比high还大,就返回左子树替代自己。
108. 将有序数组转换为二叉搜索树
https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/description/

    public TreeNode sortedArrayToBST(int[] nums) {
        if (nums.length == 0) return null;
        TreeNode node = helper(nums, 0, nums.length - 1);
        return node;
    }
    public TreeNode helper(int[] nums,int low,int high){
        if (low > high ) return null;
        int mid = low + (high - low) / 2;
        TreeNode node = new TreeNode(nums[mid]);
        node.left = helper(nums,low,mid - 1);
        node.right = helper(nums,mid + 1,high);
        return node;
    }

总结:有序数组构造平衡二叉树,每次二分查找就好,自然就是平衡的。
538. 把二叉搜索树转换为累加树
https://leetcode.cn/problems/convert-bst-to-greater-tree/description/

TreeNode pre = null;
    public TreeNode convertBST(TreeNode root) {
        if (root == null) return null;
        helper(root);
        return root;
    }
    public void helper(TreeNode node){
        if (node == null) return;
        helper(node.right);
        if (pre == null){
            node.val = node.val;
        }else {
            node.val += pre.val;
        }
        pre = node;
        helper(node.left);
    }

总结:遍历顺序:右根左,用pre记录上一个节点,每个节点的新值都是自己的旧值+pre的值。

posted @   jeasonGo  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示