Leetcode 501 二叉搜索树中的众数

题意理解

首先明确:  二叉搜索树中序遍历是严格的单调递增序列,也就是说,传统意义上得到二叉搜索树不存在相同的数,也不可能存在众数。

所以:        这里的二叉搜索树不是严格意义上的二叉搜索树,它允许重复的值,其中序遍历是不严格的单调增的序列。

又因为:     二叉搜索树是不严格的单调增序列,所以其相同的值总是挨着的

所以:         我们能从前后不相同的两个值为一个起始点,统计相同数的个数

所以:         我们能维护一个最大的count在整个遍历在整个过程中,并保存对应的元素值

解题思路

        对应两种树的遍历思路: 递归        迭代

1.递归

中间节点的处理逻辑是:

pre的值等于cur的值时,统计当前元素的count,否则count开启重置count=1

对maxCount进行更新:

        若当前count==maxCount,则当前root的值进入结果集

        若当前count>maxCount,则当前结果集清空,root的值进入结果集,maxCount=count,值更新

        若当前count

/**
     * 这里找二叉搜索树的众数,首先明确,正常的二叉搜索数不存在重复的数据,其中序遍历是严格单调增序列
     * 所以,这里的二叉树是非常规的二叉树,它允许重复的值,重复的值总是存在于左子树
     * 同时又因为二叉搜索树中序遍历是有序的,所以重复的数总是挨着的,可以一个起始点开始count++,统计出现次数
     * @param root
     * @return
     */
    //保存结果
    List resultList=new ArrayList<>();
    //双指针,是想前一个节点
    TreeNode pre=null;
    //记录当前元素重复次数
    int count=0;
    //记录最大重复次数
    int maxCount=0;
    //递归解法
    public int[] findMode(TreeNode root) {
        //中序遍历
        //左子树处理
        if(Objects.nonNull(root.left)) findMode(root.left);
        //中间节点处理
        if(pre==null||pre.val!=root.val){
            count=1;
        }else{
            count++;
        }
        //最大count更新
        if(maxCount

2.迭代

迭代和递归的中间处理逻辑是相同的,只是使用自定义栈来模拟递归过程,来防止栈溢出

//迭代解法
    public int[] findMode2(TreeNode root){
        List resultList=new ArrayList<>();
        //双指针,是想前一个节点
        TreeNode pre=null;
        //记录当前元素重复次数
        int count=0;
        //记录最大重复次数
        int maxCount=0;

        //自定义栈
        Stack stack=new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode cur=stack.peek();
            if(cur!=null){
                stack.pop();
                //中序入栈,有因为栈总是先进后出的,所以以一下顺序入栈
                //对子树进行非空判断后入栈,则子树不会导致null值入栈
                //手动null值入栈,是一个信号,即下一个值为中间节点,一定是非空的,进行识别并处理
                if(Objects.nonNull(cur.right)) stack.push(cur.right);
                stack.push(cur);
                stack.push(null);
                if(Objects.nonNull(cur.left)) stack.push(cur.left);
            }else{
                stack.pop();
                cur=stack.pop();
                //获得中间节点,中间节点的处理逻辑
                if(pre==null||pre.val!=cur.val) count=1;
                else count++;
                if(maxCount==count){
                    resultList.add(cur.val);
                } else if (maxCount

3.分析

时间复杂度:

        递归:O(n)

        迭代:O(n)

空间复杂度:

        递归:O(1)

        迭代:O(n)

        

你可能感兴趣的:(刷题训练营,算法,数据结构)