力扣第501题 二叉树的众数 c++ (暴力 加 双指针优化)

题目

501. 二叉搜索树中的众数

简单

相关标签

树   深度优先搜索   二叉搜索树   二叉树

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

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

假定 BST 满足如下定义:

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

示例 1:

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

示例 2:

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

提示:

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

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

思路和解题方法一(暴力)

  1. 定义一个私有函数searchBST,用于前序遍历二叉搜索树,并统计每个元素的频率。函数参数包括当前节点指针cur和存储元素频率的unordered_mapmap
  2. searchBST函数中,如果当前节点为空,则直接返回;否则,对当前节点的值进行统计,将当前节点的值作为map的键,并将对应的值加1,表示该元素出现的频率。
  3. 递归调用searchBST函数,传入当前节点的左子节点和map,再传入当前节点的右子节点和map,实现前序遍历。
  4. 定义一个静态成员函数cmp,用于比较两个pair类型的元素,按照频率降序排列。在排序时使用此比较函数。
  5. findMode函数中,首先创建一个空的unordered_map类型的map,用于存储元素及其频率。
  6. 如果输入的根节点为空,直接返回空的结果数组。
  7. 调用searchBST函数,传入根节点和map,统计二叉搜索树中每个元素的频率。
  8. map转化为vector类型,并使用sort函数对vector进行排序,排序方式为按照元素的频率降序排列。
  9. 创建一个空的结果数组result,将排序后的第一个元素的键(也就是出现频率最高的元素)添加到result中。
  10. 遍历排序后的vector,从第二个元素开始,如果其频率和第一个元素的频率相同,则将其键添加到result中;否则结束遍历。
  11. 返回结果数组result

复杂度

        时间复杂度:

                O(n logn)

  • 时间复杂度:

    • 前序遍历二叉树的时间复杂度为 O(n),其中 n 是二叉树的节点数。
    • 构建哈希表的过程中,对每个节点进行插入操作的平均时间复杂度为 O(1)。因此构建哈希表的时间复杂度也是 O(n)。
    • 对哈希表进行排序的时间复杂度为 O(nlogn)。
    • 综上所述,算法的时间复杂度为 O(n) + O(n) + O(nlogn) = O(nlogn)。

        空间复杂度

                O(n)

  • 空间复杂度:

    • 使用了一个哈希表来存储元素及其频率,哈希表的空间复杂度是 O(n)。
    • 将哈希表转换成了向量,空间复杂度仍然是 O(n)。
    • 保存结果的向量,最多可能存储所有节点的值,因此空间复杂度也是 O(n)。
    • 综上所述,算法的空间复杂度为 O(n)。

c++ 代码

class Solution {
private:// 前序遍历二叉搜索树,统计每个元素的频率void searchBST(TreeNode* cur, unordered_map<int, int>& map) {if (cur == NULL) return ;map[cur->val]++; // 统计元素频率searchBST(cur->left, map); // 遍历左子树searchBST(cur->right, map); // 遍历右子树return ;}// 静态成员函数,用于比较两个pair类型元素,按照频率降序排列static bool 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; // 存储元素及其频率的map,key为元素,value为频率vector<int> result; // 结果数组if (root == NULL) return result; // 根节点为空,直接返回空结果数组searchBST(root, map); // 统计二叉搜索树中每个元素的频率vector<pair<int, int>> vec(map.begin(), map.end()); // 将map转换为vectorsort(vec.begin(), vec.end(), cmp); // 按照频率降序排列result.push_back(vec[0].first); // 将频率最高的元素添加到结果数组中for (int i = 1; i < vec.size(); i++) {// 遍历排序后的vector,如果元素频率与第一个元素的频率相同,则添加到结果数组中;否则结束遍历if (vec[i].second == vec[0].second) result.push_back(vec[i].first);else break;}return result; // 返回结果数组}
};

 思路和解题方法二(双指针 加 时时优化)

  1. 使用了一个全局变量 maxCount 来记录最大频率,使用 count 来统计当前节点值出现的频率。同时,引入了一个 pre 变量来记录前一个访问的节点,以便比较当前节点与前一个节点的值是否相同。
  2. 函数 searchBST 是进行中序遍历的辅助函数,通过递归遍历左子树、处理当前节点、递归遍历右子树的顺序进行搜索。在处理当前节点时,首先判断当前节点值与前一个节点值是否相同,若相同则将 count 增加 1,否则将 count 重置为 1。然后,根据 count 的大小与 maxCount 进行比较,并更新 maxCountresult。如果 countmaxCount 相同,说明当前节点值出现的频率与最大频率相同,将其加入 result 中。如果 count 大于 maxCount,则更新 maxCount 并清空 result,将当前节点值放入 result 中。
  3. findMode 函数中,初始化各个变量,然后调用 searchBST 开始搜索,并返回结果数组 result

复杂度

        时间复杂度:

                O(n)

时间复杂度是O(n),其中n是二叉搜索树中的节点数。因为我们需要遍历所有的节点来统计它们的频率。

        空间复杂度

                O(1)

不利用额外空间

c++ 代码

class Solution {
private:int maxCount = 0; // 最大频率int count = 0; // 统计频率TreeNode* pre = NULL; // 前一个节点vector<int> result; // 存储结果的向量// 中序遍历二叉搜索树,搜索出现频率最高的节点值void searchBST(TreeNode* cur) {if (cur == NULL) return; // 递归终止条件,当前节点为空searchBST(cur->left); // 左子树// 统计频率if (pre == NULL) { // 第一个节点count = 1;} else if (pre->val == cur->val) { // 与前一个节点数值相同count++;} else { // 与前一个节点数值不同count = 1;}pre = cur; // 更新上一个节点if (count == maxCount) { // 如果和最大频率相同,将节点值放进result中result.push_back(cur->val);}if (count > maxCount) { // 如果频率大于最大频率maxCount = count;   // 更新最大频率result.clear();     // 清空result,之前result中的元素都无效了result.push_back(cur->val);}searchBST(cur->right); // 右子树return ;}public:vector<int> findMode(TreeNode* root) {count = 0;maxCount = 0;pre = NULL; // 初始化前一个节点为空result.clear(); // 清空result向量searchBST(root); // 调用中序遍历函数搜索出现频率最高的节点值return result; // 返回结果向量}
};

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/155534.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Redis】Set集合相关的命令

目录 命令SADDSMEMBERSSISMEMBERSCARDSPOPSMOVESREMSINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 命令 SADD 将⼀个或者多个元素添加到set中。注意&#xff0c;重复的元素⽆法添加到set中。 SADD key member [member ...]SMEMBERS 获取⼀个set中的所有元素&#xff0…

js事件循环详解

事件循环简介 JavaScript的事件循环是一种处理异步事件和回调函数的机制&#xff0c;它是在浏览器或Node.js环境中运行&#xff0c;用于管理任务队列和调用栈&#xff0c;以及在适当的时候执行回调函数。 事件循环的基本原理是&#xff0c;JavaScript引擎在空闲时等待事件的到…

苹果ios开发者ipa文件包内测人数签名真机数量满了应该怎么做?

苹果ios开发者ipa文件包内测人数签名真机数量满了应该怎么做&#xff1f; 有人总是问我开发者的设备满了怎么做才可以让设备增加&#xff1f;或者我要怎么做才能让员工的设备都可以安装&#xff0c;那么首先我们要做到的就是要知道我们的开发者都是拥有多少内测设备&#xff1f…

jupyter notebook如何实现代码提示功能?

jupyter notebook在数据分析中使用非常方便&#xff0c;但是没有代码提示功能&#xff0c;让人感觉有一点点遗憾&#xff1f;如何实现代码提示功能呢&#xff1f;以下实现亲测有效。 本人python版本是3.8. 首先关闭jupyter notebook&#xff0c;安装相关的库。 一、需要提前…

MongoDB——centOS7环境Mongodb权限管理(图解版)

目录 一、MongDB权限概述1.1、MongDB权限概述1.2、MongDB权限列表 二、Mongodb权限管理示例2.1、创建账号2.1.1、创建管理员用户2.1.2、开启认证2.1.3、创建普通账号 一、MongDB权限概述 1.1、MongDB权限概述 mongodb是没有默认管理员账号&#xff0c;所以要先添加管理员账号…

【Python 零基础入门】 函数

【Python 零基础入门】第五课 函数 【Python 零基础入门】第五课 函数函数在生活中的类比函数为什么要使用函数函数的格式无参函数含参函数 参数形参实参 变量作用域局部变量全局变量 递归函数基本的递归斐波那契数列 Lambda 表达式高阶函数map 函数filter 函数reduce 函数结合…

Node历史版本下载及配置npm镜像

https://nodejs.org/en/download/releases 点击对应版本Release,选择合适的包&#xff0c;进行下载安装。 配置国内镜像 npm config set registry https://registry.npmmirror.com/

Practical Memory Leak Detection using Guarded Value-Flow Analysis 论文阅读

本文于 2007 年投稿于 ACM-SIGPLAN 会议1。 概述 指针在代码编写过程中可能出现以下两种问题&#xff1a; 存在一条执行路径&#xff0c;指针未成功释放&#xff08;内存泄漏&#xff09;&#xff0c;如下面代码中注释部分所表明的&#xff1a; int foo() {int *p malloc(4 …

上海亚商投顾:沪指冲高回落 医药、芯片股全天领涨

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日小幅反弹&#xff0c;创业板指盘中涨超1.6%&#xff0c;午后涨幅有所收窄。医药医疗股全线走强&#…

LLM - 旋转位置编码 RoPE 代码详解

目录 一.引言 二.RoPE 理论 1.RoPE 矩阵形式 2.RoPE 图例形式 3.RoPE 实践分析 三.RoPE 代码分析 1.源码获取 2.源码分析 3.rotary_emb 3.1 __init__ 3.2 forward 4.apply_rotary_pos_emb 4.1 rotate_half 4.2 apply_rotary_pos_emb 四.RoPE 代码实现 1.Q/K/V …

飞桨大模型套件:一站式体验,性能极致,生态兼容

在Wave Summit 2023深度学习开发者大会上&#xff0c;来自百度的资深研发工程师贺思俊和王冠中带来的分享主题是&#xff1a;飞桨大模型套件&#xff0c;一站式体验&#xff0c;性能极致&#xff0c;生态兼容。 大语言模型套件PaddleNLP 众所周知PaddleNLP并不是一个全新的模型…

腾讯云轻量2核4G5M可容纳多少人访问?

腾讯云2核4G5M服务器支持多少人在线访问&#xff1f;卡不卡&#xff1f;腾讯云轻量2核4G5M带宽服务器支持多少人在线访问&#xff1f;5M带宽下载速度峰值可达640KB/秒&#xff0c;阿腾云以搭建网站为例&#xff0c;假设优化后平均大小为60KB&#xff0c;则5M带宽可支撑10个用户…

ad5665r STM32 GD32 IIC驱动设计

本文涉及文档工程代码&#xff0c;下载地址如下 ad5665rSTM32GD32IIC驱动设计,驱动程序在AD公司提供例程上修改得到,IO模拟的方式进行IIC通信资源-CSDN文库 硬件设计 MCU采用STM32或者GD32,GD32基本上和STM32一样,针对ad566r的IIC时序操作是完全相同的. 原理图设计如下 与MC…

matlab绘制尖角colorbar

Matlab代码 cmap [69 117 180116 173 203171 217 233254 224 144253 174 77244 109 67215 48 39165 0 38]/255; %画图的部分代码 figure set(gcf,outerposition,get(0,screensize)) ax axes(Position,[0.2 0.2 0.6 0.6]); % pos需要自己设置位置 h colorbar; % colormap(ax…

bash上下键选择选项demo脚本

效果如下&#xff1a; 废话不多说&#xff0c;上代码&#xff1a; #!/bin/bashoptions("111" "222" "333" "444") # 选项列表 options_index0 # 默认选中第一个选项 options_len${#options[]}echo "请用上下方向键进行选择&am…

Windows11下清理Docker Desktop与wsl的C盘空间占用

一、清理Docker Desktop的磁盘占用 //【查看docker 占用的空间】 docker system dfTYPE 列出了docker 使用磁盘的 4 种类型&#xff1a; Images&#xff1a;所有镜像占用的空间&#xff0c;包括拉取下来的镜像&#xff0c;和本地构建的。Containers&#xff1a;运行的容器占用…

华为云云耀云服务器L实例评测 | 实例使用教学之综合导览

华为云云耀云服务器L实例评测 &#xff5c; 实例使用教学之综合导览 实例使用教学实例场景体验实例性能评测实例评测使用介绍华为云云耀云服务器 华为云云耀云服务器 &#xff08;目前已经全新升级为 华为云云耀云服务器L实例&#xff09; 华为云云耀云服务器是什么华为云云耀云…

k8s 集群部署 kubesphere

一、最小化部署 kubesphere 1、在已有的 Kubernetes 集群上部署 KubeSphere&#xff0c;下载 YAML 文件: wget https://github.com/kubesphere/ks-installer/releases/download/v3.4.0/kubesphere-installer.yaml wget https://github.com/kubesphere/ks-installer/releases/…

力扣第530与783题 c++(暴力,加双指针优化) 附迭代版本

题目 530. 二叉搜索树的最小绝对差 783. 二叉搜索树节点最小距离 简单 相关标签 树 深度优先搜索 二叉搜索树 二叉树 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝…

阿里云存储I/O性能、IOPS和吞吐量是什么意思?

云盘的存储I/O性能是什么&#xff1f;存储I/O性能又称存储读写性能&#xff0c;指不同阿里云服务器ECS实例规格挂载云盘时&#xff0c;可以达到的性能表现&#xff0c;包括IOPS和吞吐量。阿里云百科网aliyunbaike.com分享阿里云服务器云盘&#xff08;系统盘或数据盘&#xff0…