代码随想录算法训练营第19天| LeetCode530. 二叉搜索树的最小绝对差 | 501.二叉搜索树中的众数 | 236. 二叉树的最近公共祖先

目录

题目链接:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)

题目链接:501. 二叉搜索树中的众数 - 力扣(LeetCode)

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

解题思路


    “今年的我们已与去年不同,我们的爱人亦是如此。如果变换中的我们依旧爱着那个变化中的人,这可真是个令人欣喜的意外。”  

题目链接:530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)

思路:要找到二叉搜索树(BST)中任意两不同节点值之间的最小差值,利用BST的中序遍历特性

在中序遍历中,节点值是按升序排列的,因此相邻节点的差值就是最小的。我们可以通过一次中序遍历,记录相邻节点的差值,并找出最小的差值。

class Solution530 {
    private Integer prev;  // 记录在中序遍历过程中前一个访问的节点值
    private int minDiff;  // 记录当前找到的最小差值

    public int getMinimumDifference(TreeNode root) {
        prev = null;
        minDiff = Integer.MAX_VALUE;
        inOrderTraversal(root);
        return minDiff;
    }

    // 中序遍历BST,并计算最小差值
    private void inOrderTraversal(TreeNode node) {
        if (node == null) {
            return;
        }

        // 递归遍历左子树
        inOrderTraversal(node.left);

        // 处理当前节点
        if (prev != null){
            minDiff = Math.min(minDiff, node.val - prev);
        }
        prev = node.val;

        // 递归遍历右子树
        inOrderTraversal(node.right);
    }
}

题目链接:501. 二叉搜索树中的众数 - 力扣(LeetCode)

既然是搜索树,它中序遍历就是有序的。通过中序遍历,我们可以逐个访问节点值,并统计每个值的出现次数,从而找出众数。

  1. 使用中序遍历遍历BST。
  2. 在inOrderTraversal遍历过程中统计每个值的出现次数。使用双指针思路:prev 记录前一个访问的节点值,count 记录当前节点值的出现次数,maxCount 记录最高的出现次数,result 存储所有出现次数等于最高次数的节点值。
  3. 记录最高的出现次数,并在遍历结束后找出所有出现次数等于最高次数的值。
class Solution501 {
    private Integer prev = null;
    private int count = 0;
    private int maxCount = 0;
    private List<Integer> result = new ArrayList<>();
    public int[] findMode(TreeNode root) {
        inOrderTraversal(root);
        // 将结果列表转换为数组返回
        int[] modes = new int[result.size()];
        for (int i = 0; i < result.size(); i++) {
            modes[i] = result.get(i);
        }
        return modes;
    }

    // 中序遍历BST
    private void inOrderTraversal(TreeNode node) {
        if (node == null) {
            return;
        }

        // 递归遍历左子树
        inOrderTraversal(node.left);

        // 处理当前节点
        if (prev == null || node.val != prev) {
            count = 1;
        } else {
            count++;
        }

        if (count > maxCount) {
            maxCount = count;
            result.clear();
            result.add(node.val);
        } else if (count == maxCount) {
            result.add(node.val);
        }

        prev = node.val;

        // 递归遍历右子树
        inOrderTraversal(node.right);
    }
}

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

思路:在二叉树中找到两个指定节点的最近公共祖先(LCA,Lowest Common Ancestor)问题可以使用递归来解决。公共祖先的定义是:对于树中的两个节点 𝑝和 𝑞,最近公共祖先 𝐿𝐶𝐴是这两个节点的祖先节点且深度最大

解题思路

  1. 递归定义:如果当前节点是 𝑝或 𝑞,或者当前节点的子树中包含 𝑝 和 𝑞,那么这个节点就是 𝑝 和 𝑞 的最近公共祖先。
  2. 递归函数:对每个节点,检查其左子树和右子树是否包含 𝑝 或 𝑞:
    • 如果左子树和右子树各包含一个目标节点,则当前节点是 LCA。
    • 如果两个目标节点都在左子树,递归在左子树中查找。
    • 如果两个目标节点都在右子树,递归在右子树中查找。
  3. 返回值:如果找到 𝑝 或 𝑞,则返回该节点;两边都没有找到,则返回 null

class Solution236 {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        // 如果当前节点为空,返回 null
        if (root == null) {
            return null;
        }

        // 如果当前节点是 p 或 q,返回当前节点
        if (root == p || root == q) {
            return root;
        }

        // 递归搜索左子树和右子树
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);

        // 如果在左子树和右子树都找到了 p 或 q,那么当前节点就是最近公共祖先
        if (left != null && right != null) {
            return root;
        }

        // 如果在左子树和右子树只有一边找到了 p 或 q,返回找到的那个节点
        return left != null ? left : right;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值