leetcode——二叉搜索树中的众数

本文介绍了一种从二叉搜索树(BST)中找出所有出现频率最高的元素(众数)的方法。提供了两种实现思路:一是使用unordered_map进行元素计数后排序;二是采用非递归中序遍历,通过比较相邻节点来计数。
  1. 二叉搜索树中的众数

给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。

假定 BST 有如下定义:

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

例如:
给定 BST [1,null,2,2],

1

2
/
2

返回[2].

提示:如果众数超过1个,不需考虑输出顺序

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

方法一:使用unordered_map存储遍历结果并记录次数,将结果转到vector中,排序,遍历比较得出答案。

    unordered_map<int, int> map;
    vector<int> ans;

    void dfs(TreeNode* root) 
    {
        if(root == NULL) return;
        map[root->val]++; //遍历记录每个元素
        dfs(root->left);
        dfs(root->right);
    }

    bool static cmp(pair<int, int>& a, pair<int, int>& b) { return a.second > b.second; }//自定义比较函数

    vector<int> findMode(TreeNode* root) {
        if(root == NULL) return ans;
        dfs(root);
        vector<pair<int, int>> vec(map.begin(), map.end());
        sort(vec.begin(), vec.end(), cmp);
        ans.push_back(vec[0].first);
        for(int i = 1; i < vec.size(); i++)
        {
            if(vec[i].second == vec[0].second) ans.push_back(vec[i].first);
            else break;
        }
        return ans;
    }

方法二:利用二叉排序树的性质,声明两个指针或是两个变量来记录中序遍的当前结果和上一个结果,如果某个元素重复出现,纪录其出现次数,与最大次数比较,要是相等,则记录当前数字。如果大于,则更新最大次数和答案数组。

    List<Integer> mList = new ArrayList<>();
    int curent = 0;
    int count = 0;
    int maxCount = 0;

    public int[] findMode(TreeNode root) {
        inOrderTraversal(root);
        int[] res = new int[mList.size()];
        //把集合list转化为数组
        for (int i = 0; i < mList.size(); i++) {
            res[i] = mList.get(i);
        }
        return res;
    }

    //非递归方式
    public void inOrderTraversal(TreeNode tree) {
        Stack<TreeNode> stack = new Stack<>();
        while (tree != null || !stack.isEmpty()) {
            while (tree != null) {
                stack.push(tree);
                tree = tree.left;
            }
            if (!stack.isEmpty()) {
                tree = stack.pop();
                int nodeValue = tree.val;
                if (nodeValue == curent) {
                    //如果节点值等于curent,count就加1
                    count++;
                } else {
                    //否则,就表示遇到了一个新的值,curent和count都要
                    //重新赋值
                    curent = nodeValue;
                    count = 1;
                }
                if (count == maxCount) {
                    //如果count == maxCount,就把当前节点加入到集合中
                    mList.add(nodeValue);
                } else if (count > maxCount) {
                    //否则,当前节点的值重复量是最多的,直接把list清空,然后
                    //把当前节点的值加入到集合中
                    mList.clear();
                    mList.add(nodeValue);
                    maxCount = count;
                }
                tree = tree.right;
            }
        }
    }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值