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

tips:

  1. 二叉搜索树一定是中序遍历,因为只有中序遍历二叉搜索树它的元素才是有序的。
  2. 回溯法则使用后序遍历方式,左右中,主要处理逻辑在中。采用后序是因为中的处理逻辑需要左分支和右分支递归带回来的处理结果,从而通过递归左右中的方式把结果一层层向上带。

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

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //中序遍历双指针法
    //用来记录上一个遍历的结点
    TreeNode pre;
    //将结果初始化为最大值,便于存储二叉搜索树中最小值
    int result = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        //若二叉树为空,则直接返回最小值0
        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.二叉搜索树中的众数

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    //记录当前元素出现次数
    int count;
    //记录元素出现最大次数
    int maxCount;
    //记录前一个结点
    TreeNode pre;
    //记录结果
    ArrayList<Integer> resultList;

    //主函数
    public int[] findMode(TreeNode root) {
        resultList = new ArrayList<>();
        maxCount = 0;
        count = 0;
        pre = null;
        search(root);
        //将ArrayList容器中的结果转移到数组中,从而返回结果数组
        int[] result = new int[resultList.size()];
        for(int i = 0; i < resultList.size(); i++){
            result[i] = resultList.get(i);
        }
        return result;
    }

    //递归函数
    void search(TreeNode root){
        //若遍历到空结点,直接返回
        if(root == null){
            return;
        }

        //左处理
        search(root.left);

        //中处理
        if(pre == null){
            //当pre还未开始移动时,初始化指向的为null,执行
            //此时cur的元素只出现了一次,count修改为1
            count = 1;
        }else if(pre.val == root.val){
            //当pre与cur指向结点值相同时,说明cur的元素出现了一次重复,count自增1
            count++;
        }else{
            //当pre与cur指向结点值不同时,说明当前元素出现次数统计结束,count归1
            count = 1;
        }
        //指针中处理结束,更新结果以及maxCount
        //tips:若count < maxCount,则不走以下分支结构,为正常情况,只向后移动双指针即可
        if(count > maxCount){
            //若当前元素次数大于最大次数
            resultList.clear();
            resultList.add(root.val);
            maxCount = count;
        }else if(count == maxCount){
            resultList.add(root.val);
        }
        //为使cur与pre形成双指针
        pre = root;

        //右处理
        search(root.right);
    }
}

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

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    //自底向上,后序,递归,回溯
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        //递归出口处理
        //若传入二叉树为空或者遍历的结点为空,返回null
        if(root == null){
            return null;
        }
        //当遍历到p或者q结点,则直接返回当前结点(p或者q)
        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){
            //若未找到p或q,则返回null
            return null;
        }else if(left == null && right != null){
            //若左分支无p或q,右分支找到p或q,返回右分支
            return right;
        }else if(left != null && right == null){
            //若右分支无p或q,左分支找到p或q,返回左分支
            return left;
        }else{
            //若左右结点返回值均不为空,则说明同时找到p和q
            return root;
        }
    }
}

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值