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

本文介绍了如何利用二叉搜索树的特性解决三种不同的编程问题:最小绝对值、众数查找和最近公共祖先。在解决这些问题时,作者强调了中序遍历和双指针法的重要性,并提供了详细的代码实现。对于二叉树的最近公共祖先问题,作者指出需要采用后序遍历并涉及回溯。同时,文章提醒读者注意递归的三个步骤和变量的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


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

思路

二叉搜索树的特点:根节点的值大于所有左子树的值,小于所有右子树的值;按照此特点采用中序遍历,获得的值是一直递增的;
本题是要获得相邻节点差值的最小绝对值,按照“中序遍历”,后一个节点值一定是比上一个节点值大的;所以可以使用双指针法,设置一个pre指针指向上一节点,与当前节点值相减,因为当前节点肯定大于上一个节点值,所以相减的差值一定是正数,就不用额外的Math类的abs方法了;在取得最小值后,要给pre节点赋值,又继续开始下一轮直到结束找到最小的绝对值。

注意

使用“双指针法”,记得要给pre节点赋值!!!

实现代码

 //使用双指针法
class Solution {
    TreeNode pre;
    int res=Integer.MAX_VALUE;
    public int getMinimumDifference(TreeNode root) {
        getMin(root);
        return res;     
    }
    public void getMin(TreeNode root){
        if(root==null){
            return;
        }
        //左
        getMin(root.left);

        //中
        if(pre!=null&&pre.val<root.val){
            res=Math.min(res,root.val-pre.val);
        }
        pre=root;

        //右
        getMin(root.right);
    }
}

501.二叉搜索树中的众数

思路

“双指针法”
二叉搜索树的特点:根节点的值大于所有左子树的值,小于所有右子树的值;
按照“中序遍历”,获得的节点值是递增的,那么就是说:相同的节点值都是排在一起的。

需要的变量:

  1. 指向上一节点的指针pre
  2. 存放出现频率高的节点值的集合list
  3. 统计当前节点值出现次数的count
  4. 出现次数最多的maxcount

首先是找到结束的条件,然后注意要中序遍历;对中的处理是:首先当pre指针不为空时指向的节点值1.若与当前节点值相同,统计出现次数的变量count++,统计频率;2.若不相同,说明节点值不同,那么此节点值只出现一次,即count=1;然后判断当前的maxcount是否最大,与count比较,若count>maxcount,那么说明出现了频率更大的节点值,要将原来集合里面存放的节点值clear()清除完全,再将当前出现频率最高的节点值加入集合,最后给maxcount赋值为count;另外一个可能是maxcount=count,那么直接就将这个count对应的节点值加入到集合中;最后的最后千万不要忘记给pre指针赋值。

注意

1.说到count=maxcount时,直接将对应的节点值加入集合中是因为:众数不一定只有一个,可以有多个。
2.注意判断count=1时的条件,一个是pre指针指向节点值不等于当前节点值,另外一个是当pre指针为空时!!!

实现代码

//双指针法
class Solution {
    List<Integer> list;
    TreeNode pre;
    int maxcount;
    int count;
    public int[] findMode(TreeNode root) {
        list=new ArrayList<>();
        pre=null;
        count=0;
        maxcount=0;
        getMax(root);
        int [] arr=new int[list.size()];
        for(int i=0;i<list.size();i++){
            arr[i]=list.get(i);
        }
        return arr;
    }

    public void getMax(TreeNode root){
        if(root==null){
            return;
        }
        getMax(root.left);
        //此判断要注意
        if(pre==null||pre.val!=root.val){
            count=1;
        }else{
            count++;
        }
        if(count>maxcount){
            list.clear();
            list.add(root.val);
            maxcount=count;
        }else if(count==maxcount){
            list.add(root.val);
        }
        pre=root;

        getMax(root.right);
    }
}

236.二叉树的最近公共祖先(二刷重点关注题目)

此题可以理解过程,但是代码实现过程没有办法写出来,所有思路不清晰,二刷再注意再再理解!!!

思路

两个节点要找祖父就是按照从下往上反馈,也就是需要“后序遍历”!!!
然后当遍历到要求的两个节点时,需要返回他们的根节点,这就需要涉及到回溯,然后一层层往上回溯将这个祖父返回到根节点获得。
使用后序遍历时获得当前节点的左右节点递归出的结果,然后对这获得的节点进行判断确定返回值。

注意

涉及到“回溯”!!!

实现代码

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
       if(root==null){
           return null;
       }
       //当当前节点遍历到p或q时,返回他们的父节点,要从下往上:回溯
       if(root==p||root==q){
           return root;
       }

       //因为要找到p/q,返回他们共同的最近祖先,所以是从下往上反馈就是后序遍历
       //左
       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.二叉搜索的特点一定要用,关于值关于遍历都要记得;
2.关于二叉树的最近公共祖先问题,可以理解整个流程,但是在用代码实现的能力还不够,二刷需要额外关注此题。
3.从开始一直说的递归三部曲,首先找到结束的条件;然后是单层逻辑;最后是递归(按照怎么样的顺序呢?);今天对这递归三部曲比较能理解和按照这个流程了。
4.关于变量的问题,是需要是公共变量还是局部变量就可以了,今天在变量上面犯难了,后序需要研究一下这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值