代码随想录Day23

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

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

思路:需要两两做差,层序遍历之后套两个for循环?应该可以利用一下二叉搜索树的特点,遍历每一个节点,求左右孩子跟自己的差,然后对比当前的最小绝对差,

递归三步曲

1、参数:当前节点,目前最小绝对差

2、终止条件:扫描到叶子节点

3、单层逻辑:分别求左右孩子跟自己的差值,更新条件是发现了更小的绝对差

尝试(部分AC)
class Solution {
    private int result = Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        if(root == null) return result;
        int left = 0;
        int right = 0;
        if(root.left != null){
           left = Math.abs(root.left.val - root.val);
            if(left < result) result = left;
        }
        if(root.right != null){
            right = Math.abs(root.right.val - root.val);
            if(right < result) result = right;
        }
        getMinimumDifference(root.right);
        getMinimumDifference(root.left);
        return result;
    }
}

只能部分通过,我想的是【最小差值出现在相邻的两层】。事实上不是,题目说了是任意的节点,难道说先遍历一遍,排个顺序,再两两做差?想不通了。 

答案
// 递归法
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.二叉搜索树中的众数

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

思路:前序遍历,用map来存,记录最大值,取出最大值对应的所有key,不知道map有没有这个操作

尝试(暴力AC)
class Solution {
    public Map<Integer, Integer> map = new HashMap<>();
    public int maxCount = 0;

    public int[] findMode(TreeNode root) {
        if (root == null) return new int[0];
        midOrder(root);
        
        // 使用ArrayList来收集众数
        List<Integer> modes = new ArrayList<>();
        for (Integer key : map.keySet()) {
            if (map.get(key) == maxCount) {
                modes.add(key);
            }
        }
        
        // 将ArrayList转换为数组
        int[] result = new int[modes.size()];
        for (int i = 0; i < modes.size(); i++) {
            result[i] = modes.get(i);
        }
        return result;
    }

    public void midOrder(TreeNode root) {
        if (root == null) return;
        midOrder(root.left);
        
        // 更新计数并根据需要更新maxCount
        map.put(root.val,map.getOrDefault(root.val,0)+1);
        maxCount = Math.max(map.getOrDefault(root.val,0), maxCount);
        midOrder(root.right);
    }
}
答案
// 中序遍历
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;
        // 计数,第一个节点,和第一次出现的节点,给count赋值 1
        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);
    }
}
小结

🍉动态数组转换为普通数组

        ArrayList<Integer> resList = new ArrayList<>();
        int[] res = new int[resList.size()];
        for (int i = 0; i < resList.size(); i++) {
            res[i] = resList.get(i);
        }

🍉之所以可以实现一次遍历就搞定,是有一个清空数组【reList.clear()】的操作,每次检测到【count > maxCount】就重置返回结果

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

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

思路:一整个人直接懵掉

尝试(标题4)

//尝试
答案
class Solution {
    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){
            return null;
        }else if(left == null && right !=null){
            return right;
        }else if(left != null && right == null){
            return left;
        }else{
            return root;
        }
    }
}
小结

🍉递归三部曲

1、返回值:节点,找到 q 或者 p 就返回

2、终止条件:遇到空 或者是 找到了 p q

3、单层递归逻辑:需要接住左、右孩子的返回值,根据返回值进行判断

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值