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

目录

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

501.二叉搜索树中的众数

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


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

需要领悟一下二叉树遍历上双指针操作,优先掌握递归 

题目链接/文章讲解:代码随想录

题解思路:

双指针确实快,多看卡哥视频思路讲解!!然后这题的主要是利用二叉搜索树的特性,进行中序遍历一定是递增的,通过双指针,用后一个节点的数值减去前一个节点pre的val值,然后找到连续的两两节点差值的最小即是本题所要返回的树中任意两不同节点值之间的最小差值。

/**
 * 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 = null;
    int result = Integer.MAX_VALUE;

    public int getMinimumDifference(TreeNode root) {
        traverse(root);
        return result;
    }

    public void traverse(TreeNode node){
        if(node == null) return;
        traverse(node.left);
        if(pre != null){
            result = Math.min(result, node.val - pre.val);
        }
        pre = node;
        traverse(node.right);
    }
}

501.二叉搜索树中的众数

和 530差不多双指针思路,不过 这里涉及到一个很巧妙的代码技巧。

可以先自己做做看,然后看我的视频讲解:代码随想录

题解思路:

这里利用了二叉树的特性,使用双指针方法实现!!!多听卡哥视频的思路,学会融汇贯通!!!确实很巧妙,只需要遍历一遍二叉树即可得到答案,主要的原因就是每递归一次的时候就不断的更新检查maxCount是不是当前出现最高频率的元素,然后集合中也是不断去更新的,如果出现还有比之前次数更多的元素,就先把集合中的元素删除掉,然后再添加当前的元素!!!非常之巧妙就是说,卡哥YYDS!!!

/**
 * 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 = 0;
    int maxCount = 0;
    List<Integer> list = new ArrayList<>();
    TreeNode pre = null;

    public int[] findMode(TreeNode root) {
      traverse(root);
      return list.stream().mapToInt(Integer::intValue).toArray();
    }

    public void traverse(TreeNode node){
        if(node == null) return;
        traverse(node.left); //左
        //中
        //先统计单个元素出现的pinlv
        if(pre == null) count = 1; //说明遍历到叶子节点了,此时将该叶子节点的count置为1
        else if(pre.val == node.val) count++;    //如果前一个节点的val值等于后一个节点的val值,则将该元素出现的次数加1
        else if(pre.val != node.val) count = 1; //如果前一个节点的val值不等于后一个节点的val值,则count重置为1
        //每递归一次,更新一次list集合的出现最高频率的元素,一开始令出现最高频率为0
        if(count == maxCount) list.add(node.val); //
        else if(count > maxCount){
            maxCount = count;
            list.clear(); //如果有比之前元素出现的次数还要多,就把之前list中的元素删除掉,重新添加现在的节点的元素值,这就是在不断的更新集合中出现最高频率的元素
            list.add(node.val);
        }
        pre = node; //双指针的一个重要步骤,这里指定的就是前一个节点的指针
        traverse(node.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) {
        //第二步:确定终止条件
        if(root == null) return null;
        if(root == p || root == q) return root;

        //第三步:确定单层处理逻辑,后序遍历,自底向上查找,再回溯!!!
        TreeNode left = lowestCommonAncestor(root.left, p, q); //左 返回左子树中是p或者q的节点
        TreeNode right = lowestCommonAncestor(root.right, p, q); //右 返回右子树中是p或者q的节点
        //中
        if(left != null && right != null) return root; //说明left是p和q中的一个,right是p和q中的一个,由于p和q一定不相等,而且都在二叉树中
        else if(left == null && right != null) return right;//说明right里面是p和q中的一个,因此需要回溯,向上一个节点返回
        else if(left != null && right == null) return left; //说明left里面有p和q中的一个,因此需要回溯,向上一个节点返回
        return null; //如果left中和right中都没有p和q,那么直接返回null即可

    }

}

猜你喜欢

转载自blog.csdn.net/tore007/article/details/130597666