day19 236. 二叉树的最近公共祖先&&501. 二叉搜索树中的众数&&530. 二叉搜索树的最小绝对差

  1. 二叉树的最近公共祖先(LeetCode 236)
    功能概述
    在给定的二叉树中,找出两个指定节点 p 和 q 的最近公共祖先(LCA)。
    实现思路
    高效递归方法:
    递归结束条件为当前节点 root 为空或者等于 p 或 q,此时直接返回 root。
    分别递归遍历左子树和右子树,根据左右子树的返回结果判断 LCA 的位置。
    低效路径查找方法:
    先通过 finedPath 方法找出从根节点到节点 p 的路径,存储在 pathP 中。
    从 pathP 的末尾开始向前遍历,对于每个节点,使用 fined 方法判断节点 q 是否在该节点的子树中,若存在则该节点为 LCA。
    复杂度分析
    高效递归方法:时间复杂度为 (O(n)),空间复杂度为 (O(h)),其中 (n) 是树中节点的数量,(h) 是树的高度。
    低效路径查找方法:时间复杂度为 (O(n^2)),空间复杂度为 (O(n))。

//236. 二叉树的最近公共祖先
//效率高一点 7ms
/*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;
    }
}*/
//效率低一点 8ms
boolean flag = true;
List<TreeNode> path=new ArrayList<>();
List<TreeNode> pathP;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    if (root == null || p == null || q == null) return null;
    finedPath(root,p);
    for (int i = pathP.size() - 1; i >= 0; i--) {
        TreeNode node = pathP.get(i);
        if(fined(node,q)) return node;
    }
    return null;
}
private void finedPath(TreeNode root, TreeNode p) {
    if (root == null) return;
    path.add(root);
    if (root.val == p.val) {
        pathP=new ArrayList<>(path);
        flag=false;
        return;
    }
    if (flag) finedPath(root.left, p);
    if (flag) finedPath(root.right, p);
    path.remove(path.size()-1);
}
private boolean fined(TreeNode root, TreeNode p) {
    if (root == null) return false;
    if (root.val == p.val) {
        return true;
    }
    return fined(root.left, p) || fined(root.right, p);
}
  1. 二叉搜索树中的众数(LeetCode 501)
    功能概述
    找出给定二叉搜索树(BST)中出现频率最高的元素(众数)。
    实现思路
    中序遍历方法:
    利用 BST 中序遍历结果为有序序列的特性,通过一次中序遍历统计每个元素的出现频率。
    使用 count 记录当前元素的出现次数,maxCount 记录最大出现次数,resList 存储众数。
    暴力算法:
    先通过深度优先搜索(DFS)遍历树,使用 Map 统计每个元素的出现次数。
    找出最大出现次数,然后遍历 Map 找出所有众数。
    复杂度分析
    中序遍历方法:时间复杂度为 (O(n)),空间复杂度为 (O(h)),其中 (n) 是树中节点的数量,(h) 是树的高度。
    暴力算法:时间复杂度为 (O(n)),空间复杂度为 (O(n))。
    //501. 二叉搜索树中的众数
    //中序遍历
    ArrayList resList;
    int maxCount;
    int count;
    TreeNode pre;
    public int[] findMode(TreeNode root) {
    resList = new ArrayList<>();
    maxCount = 0;
    count = 0;
    pre = null;
    findMode1(root);
    int[] res = new int[resList.size()];
    for (int i = 0; i < resList.size(); i++) {
    res[i] = resList.get(i);
    }
    return res;
    }

    public void findMode1(TreeNode root) {
    if (root == null) {
    return;
    }
    //先处理左子树
    findMode1(root.left);
    //处理方式
    int rootValue = root.val;
    // 计数
    if (pre == null || rootValue != pre.val) {
    count = 1;
    } else {
    count++;
    }
    // 更新结果以及maxCount
    if (count > maxCount) {
    resList.clear();
    resList.add(rootValue);
    maxCount = count;
    } else if (count == maxCount) {
    resList.add(rootValue);
    }
    pre = root;
    //最后处理右子树
    findMode1(root.right);
    }
    //暴力算法 8ms
    /public int[] findMode(TreeNode root) {
    Map<Integer, Integer> map = new HashMap<>();
    List list = new ArrayList<>();
    dfsFindMode(root,map);
    int max = Integer.MIN_VALUE;
    for (Map.Entry<Integer, Integer> e : map.entrySet()) {
    if (e.getValue() > max) {
    max = e.getValue();
    }
    }
    for (Map.Entry<Integer, Integer> e : map.entrySet()) {
    if (e.getValue() == max) {
    list.add(e.getKey());
    }
    }
    return list.stream().mapToInt(i -> i).toArray();
    }
    private void dfsFindMode(TreeNode root,Map<Integer, Integer> map) {
    if (root == null) return;
    map.put(root.val, map.getOrDefault(root.val, 0) + 1);
    dfsFindMode(root.left, map);
    dfsFindMode(root.right, map);
    }
    /

  2. 二叉搜索树的最小绝对差(LeetCode 530)
    功能概述
    计算给定二叉搜索树中任意两个节点之间的最小绝对差值。
    实现思路
    对于每个节点 root,分别找到其左子树中的最大值节点 cur1 和右子树中的最小值节点 cur2。
    计算 cur1 与 root、cur2 与 root 的绝对差值,更新最小绝对差值 res。
    递归遍历左子树和右子树。
    复杂度分析
    时间复杂度为 (O(n^2)),空间复杂度为 (O(h)),其中 (n) 是树中节点的数量,(h) 是树的高度。
    //530. 二叉搜索树的最小绝对差
    private int res=Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
    if (root == null) return -1;
    dfsGetMinimumDifference(root);
    return res;
    }
    private void dfsGetMinimumDifference(TreeNode root) {
    TreeNode cur1 = root.left;
    if (cur1!=null) {
    while (cur1.right!=null) cur1 = cur1.right;
    if (Math.abs(cur1.val-root.val)<res) res=Math.abs(cur1.val-root.val);
    dfsGetMinimumDifference(root.left);
    }
    TreeNode cur2 = root.right;
    if (cur2!=null) {
    while (cur2.left!=null) cur2 = cur2.left;
    if (Math.abs(cur2.val-root.val)<res) res=Math.abs(cur2.val-root.val);
    dfsGetMinimumDifference(root.right);
    }
    }

posted @ 2025-02-11 00:13  123木头人-10086  阅读(37)  评论(0)    收藏  举报