代码随想录训练营 二叉树 part7

一、二叉搜索树的最小绝对差 

530. 二叉搜索树的最小绝对差 - 力扣(LeetCode)

二叉搜索树可是有序的。

二叉搜索树采用中序遍历,其实就是一个有序数组。

把二叉搜索树转换成有序数组,然后遍历一遍数组,就统计出来最小差值了。

//递归
class Solution {
    TreeNode pre;// 记录上一个遍历的结点
    int result = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
       if(root==null)return 0;
       traversal(root);
       return result;
    }
    public void traversal(TreeNode root){
        if(root==null)return;
        //左
        traversal(root.left);
        //中
        if(pre!=null){
            result = Math.min(result,root.val-pre.val);
        }
        pre = root;
        //右
        traversal(root.right);
    }
}

二、二叉搜索树中的众数 

501. 二叉搜索树中的众数 - 力扣(LeetCode)

如果不是二叉搜索树,最直观的方法一定是把这个树都遍历了,用map统计频率,把频率排个序,最后取前面高频的元素的集合。

具体步骤如下:

     1.这个树都遍历了,用map统计频率

至于用前中后序哪种遍历也不重要,因为就是要全遍历一遍,怎么个遍历法都行,层序遍历都没毛病!

     2.把统计的出来的出现频率(即map中的value)排个序

     3.取前面高频的元素

既然是搜索树,它中序遍历就是有序的。

//中序遍历-不使用额外空间,利用二叉搜索树特性

class Solution {
    ArrayList<Integer> 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);
    }
}

三、二叉树的最近公共祖先  

236. 二叉树的最近公共祖先 - 力扣(LeetCode)

Krahets的题解。

若 root是 p,q 的 最近公共祖先 ,则只可能为以下情况之一:

p 和 q在 root 的子树中,且分列 root 的 异侧(即分别在左、右子树中);
p=root ,且 q 在 root 的左或右子树中;
q=root ,且 p 在 root 的左或右子树中;

考虑通过递归对二叉树进行先序遍历,当遇到节点 p或 q 时返回。从底至顶回溯,当节点 p,q在节点 root 的异侧时,节点 root 即为最近公共祖先,则向上返回 root 。

递归解析:
终止条件:
                 当越过叶节点,则直接返回 null ;
                 当 root等于 p,q ,则直接返回 root ;
递推工作:
                 开启递归左子节点,返回值记为 left ;
                开启递归右子节点,返回值记为 right;
                返回值: 根据 left 和 right ,可展开为四种情况;
                当 left 和 right 同时为空 :说明 root的左 / 右子树中都不包含 p,q ,返回 null;
                当 left和 right同时不为空 :说明 p,q 分列在 root 的 异侧 (分别在 左 / 右子树),因此                  root 为最近公共祖先,返回 root;
                当 left 为空 ,right 不为空 :p,q都不在 root 的左子树中,直接返回 right 。具体可分为                    两种情况:
                               p,q 其中一个在 root 的 右子树 中,此时 right 指向 p(假设为 p );
                               p,q 两节点都在 root 的 右子树 中,此时的 right 指向 最近公共祖先节点 ;
                               当 left不为空 , right为空 :与情况 3. 同理;、

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if (root == null || root == p || root == q) {
            //只要当前根节点是p和q中的任意一个,就返回(因为不能比这个更深了,再深p和q中的一个就没了)
            return root;
        }
        //根节点不是p和q中的任意一个,那么就继续分别往左子树和右子树找p和q
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        //p和q都没找到,那就没有
        if(left == null && right == null) {
            return null;
        }
        //左子树没有p也没有q,就返回右子树的结果
        if (left == null) {
            return right;
        }
        //右子树没有p也没有q就返回左子树的结果
        if (right == null) {
            return left;
        }
        //左右子树都找到p和q了,那就说明p和q分别在左右两个子树上,所以此时的最近公共祖先就是root
        return root;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿玛兰妲。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值