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

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

一. 二叉树相关算法题

530.二叉搜索树的最小绝对差

递归

思路
  • 根据据二叉搜索树中序遍历的顺序性最小绝对差一定是相邻的两个节点
class Solution {
    int min = Integer.MAX_VALUE;
    TreeNode pre = null;
    public int getMinimumDifference(TreeNode root) {
        if (root == null) return -1;
        //左
        getMinimumDifference(root.left);
        //中
        if (pre != null){
            int sub = Math.abs(root.val-pre.val);
            min = Math.min(min,sub);
        }
        pre = root;
        //右
        getMinimumDifference(root.right);
        return min;

    }
}

501.二叉搜索树中的众数

递归

思路
  • 针对普通二叉树查找众数的逻辑
    1. 递归遍历二叉树将节点value与出现次数放入map中
    2. 针对出现次数排序
    3. 返回次数最大的节点
class Solution {
    Map<Integer, Integer> map = new HashMap<>();

    public int[] findMode(TreeNode root) {
        // 节点计算频率存入
        getMap(root);

        //排序
        List<Map.Entry<Integer,Integer>> entryList = map.entrySet().stream()
                .sorted((c1, c2) -> c2.getValue().compareTo(c1.getValue()))
                .collect(Collectors.toList());
        List<Integer> resList = new ArrayList<>();
        //返回并列第一的节点
        resList.add(entryList.get(0).getKey());
        for (int i = 1; i < entryList.size(); i++) {
            if (entryList.get(i).getValue() == entryList.get(0).getValue()){
                resList.add(entryList.get(i).getKey());
            }
        }
        return resList.stream().mapToInt(Integer::intValue).toArray();
    }

    public void getMap(TreeNode root) {
        if (root == null) return;
        map.put(root.val, map.getOrDefault(root.val,0)+1);
        getMap(root.left);
        getMap(root.right);
    }
}
  • 针对本题是二叉搜索树,根据二叉搜索树的特性使用中序遍历的话,二叉树是顺序递增的,相同节点指定相邻,可以使用双指针判断
class Solution {

    int maxCount = 0;
    int count = 0;
    TreeNode pre = null;
    List<Integer> res = new ArrayList<>();
    public int[] findMode(TreeNode root) {
        searceBST(root);
        return res.stream().mapToInt(Integer::intValue).toArray();
    }

    public void searceBST(TreeNode root) {
        if (root == null) return;
        searceBST(root.left); //左
        //中
        if (pre == null){ //第一个节点
            count = 1;
        }else if (pre.val== root.val) { //与前一个节点相等
            count++;
        }else { //与前一个节点不等
            count = 1;
        }
        pre = root;
        if (count == maxCount){ //重复最大频率节点
            res.add(root.val);
        }

        //最大频率节点更新
        if (count>maxCount){
            res.clear();
            res.add(root.val);
            maxCount = count;
        }
        searceBST(root.right); //右
    }
}

236.二叉树的最近公共祖先

思路
  • 寻找公共祖先要从下向上遍历那么就要使用后序递归遍历了:
  1. 查找是否有个节点的左右子树能够分别找到p和q,如果找到返回当前节点
  2. 如果只找到一个则返回这一个并向上回溯
  3. 针对p和q其中一个是公共祖先的情况配合第二步+上递归终止条件遇见p或者q就返回这两步就能覆盖这种情况,因为遇到p或则q 直接返回就不会向下查找自然返回的那个就是公共祖先
class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {

        //递归终止条件
        if (root == null) return null;
        if (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 root;
        // 如果只有一个子树不为空那么就回溯寻找另一个子树,注意这里也覆盖了情况二节点本身也是公共祖先的情况:
        // 如果当前节点就是公共祖先的话直接就返回当前节点不会向下递归另一个节点
        else if (left == null && right != null) return right;
        else if (left != null && right == null) return left;
        else return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值