leetcode 二叉树 501. 二叉搜索树中的众数

501. 二叉搜索树中的众数

难度简单

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:

  • 结点左子树中所含节点的值 小于等于 当前节点的值
  • 结点右子树中所含节点的值 大于等于 当前节点的值
  • 左子树和右子树都是二叉搜索树

示例 1:

输入:root = [1,null,2,2]
输出:[2]

示例 2:

输入:root = [0]
输出:[0]

提示:

  • 树中节点的数目在范围 [1, 104] 内
  • -105 <= Node.val <= 105

进阶:你可以不使用额外的空间吗?(假设由递归产生的隐式调用栈的开销不被计算在内)

分析:求出现频率最高的元素集合(可能存在多个总数),看到二叉搜索树马上想到中序遍历有序,使用中序遍历+双指针来解决,用 pre 指针指向前一个节点,cur 指针指向当前节点,比较两个节点的值是否相等。count 为当前统计的频率次数,maxCount为最大频率次数。一共有三种情况,当 pre 指针为空时,当前 cur 指针指向第一个元素count 为 1;当 pre 指针和 cur 指针的值相等时,count++;当 pre 指针 和 cur 指针的值不相等时,count 重新赋值为 1。若count == maxCount就将该元素加入list集合里,若count > maxCount则更新maxCount的值,清空list集合,重新添加当前元素到list集合。

class Solution {

    int count = 0;      // 统计频率
    int maxCount = 0;   // 最大频率
    TreeNode pre = null;
    List<Integer> list = new ArrayList<>();

    public int[] findMode(TreeNode root) {

        traversal(root);
        int[] res = new int[list.size()];

        for (int i = 0; i < list.size(); i++){
            res[i] = list.get(i);
        }

        return res;
    }

    // 二叉搜索树 中序遍历
    public void traversal(TreeNode cur){

        if (cur == null)
            return;

        traversal(cur.left);                // 左
                                            // 中
        if (pre == null){   // 第一个节点
            count = 1;
        }else if (pre.val == cur.val){  // 与前一个节点值相同
            count++;
        }else{  // 与前一个节点值不同
            count = 1;
        }
        pre = cur;  // 更新前一个节点

        if (count == maxCount){     // 若当前统计频率和最大频率相同,放进list中
            list.add(cur.val);
        }

        if (count > maxCount){      // 若当前统计频率大于最大频率
            maxCount = count;       // 更新最大频率
            list.clear();           // 清空list
            list.add(cur.val);
        }

        traversal(cur.right);               // 右

        return;
    }
}

执行结果:

通过

显示详情

添加备注

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:42.2 MB, 在所有 Java 提交中击败了34.90%的用户

通过测试用例:23 / 23

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值