当前位置: 首页 > article >正文

求二叉搜索树中的众数的三种方法

题目描述

在这里插入图片描述

法一:借助数组

将树中的元素中序遍历转移进数组中,依次遍历数组,计算每个元素出现的次数count,并及时更新最大数量maxCount,将对应的众数放入ans数组中。
该方法时间复杂度和空间复杂度均为O(n)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),
 * right(right) {}
 * };
 */
class Solution {
public:
    void midT(TreeNode* root, vector<int>& treeArr) {
        if (root == NULL) {
            return;
        }
        midT(root->left, treeArr);
        treeArr.push_back(root->val);
        midT(root->right, treeArr);
        return;
    }
    vector<int> findMode(TreeNode* root) {
        vector<int> treeArr;
        vector<int> ans;
        midT(root, treeArr);//将树中的元素转移到数组中
        int base=treeArr[0];//base是当前正在累加count的元素
        int count=0, maxCount=-1;
        treeArr.push_back(-1e5-1);//防止数组中最后一个元素检测不到
        int n=size(treeArr);

        for(int i=0; i<n; i++){
            if(base != treeArr[i]){//意味着base计数已经结束
                if(maxCount == count){//意味着base是当前遍历过的元素的众数之一
                    ans.push_back(base);
                }
                else if(maxCount < count){//意味着新的、数量更多的众数出现了
                    ans.clear();
                    ans.push_back(base);
                }

				//更新
                maxCount = max(maxCount, count);
                base = treeArr[i];
                count = 0;
            }
            count++;
        }
        return ans;

    }
};

法二:借助哈希表

将树中元素转移到哈希表,获取各元素出现的次数,再将哈希表转为vector二维数组并降序排序,其第一个元素就是众数之一,然后根据数量获取其他众数即可。该方法时间复杂度O(nlogn),空间复杂度O(n)

class Solution {
private:
    void searchBST(TreeNode* root, unordered_map<int,int>& map){
        if(root == NULL){
            return;
        }
        map[root->val]++;
        searchBST(root->left, map);
        searchBST(root->right, map);
        return;
    }
    bool static cmp(const pair<int,int>& a, const pair<int,int>& b){//降序排序
        return a.second > b.second;
    }
public:
    vector<int> findMode(TreeNode* root) {
        unordered_map<int, int> map;
        vector<int> ans;
        searchBST(root, map);//将树中元素转入哈希表
        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;
    }
};

法三:直接在树上获取

这个方法用于完成进阶的要求,在中序遍历中直接完成,pre指向当前结点的前一个结点,便于比较是否相同,按照法一的逻辑进行更新。该方法时间复杂度和空间复杂度均为O(n),但是没有了额外的空间开销。


class Solution {
private:
    int count, maxCount;
    TreeNode* pre;
    vector<int> ans;

    void searchBST(TreeNode* root){//中序遍历
        if(root == NULL){
            return;
        }
        searchBST(root->left);//左

		//中
        if(pre == NULL){//第一个元素
            count = 1;
        }else if(root->val == pre->val){//同一个元素
            count++;
        }else{//下一个元素
            count = 1;
        }

		//更新最大值的逻辑同法一
        if(maxCount == count){
            ans.push_back(root->val);
        }else if(maxCount < count){
            maxCount = count;
            ans.clear();
            ans.push_back(root->val);
        }
        pre = root;

        searchBST(root->right);//右
        return;
    }
    
public:
    vector<int> findMode(TreeNode* root) {
        count = 0;
        maxCount = 0;
        pre = NULL;
        ans.clear();
        searchBST(root);
        return ans;
    }
};

http://www.kler.cn/a/599468.html

相关文章:

  • [Android] NFC卡模拟 9.05 模拟NFC门禁卡 电梯卡等 手机代替卡片
  • <项目> 高并发服务器的HTTP协议支持
  • QML指示控件:ScrollBar与ScrollIndicator
  • 复杂任务需要多agent协同处理,对其进行逻辑编排和参数调用
  • 鸿蒙特效教程10-卡片展开/收起效果
  • 数据结构篇:空间复杂度和时间复杂度
  • netplan是如何操控NetworkManager的? 笔记250324
  • 车载以太网网络测试 -23【TCPUDP通信示例】
  • 蓝桥杯——嵌入式学习日记
  • 借助AI Agent实现数据分析
  • Python虚拟环境:从入门到实战指南
  • 在 ASP.NET Core 中实现限流(Rate Limiting):保护服务免受滥用与攻击
  • ABB机器人更换机器人本体编码器电池的具体步骤
  • 蓝桥杯,冬奥大抽奖
  • 中间件解析漏洞之Tomcat集合
  • 操作系统必知的面试题
  • Maven 构建配置文件
  • 计算机操作系统(四) 操作系统的结构与系统调用
  • 盖泽 寻边器 帮助类
  • C#中状态机Stateless初使用