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

力扣第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; // 返回结果向量}
};

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

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

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

相关文章:

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

题目 501. 二叉搜索树中的众数 简单 相关标签 树 深度优先搜索 二叉搜索树 二叉树 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;。 …...

MARKDOWN 文档图片编码嵌入方案

#1 写在前面 开始写这篇文章时&#xff0c;标题怎么定困扰我良久&#xff0c;缘于不晓得如何给接下来要做的事定个简单明了的标题&#xff1a;在&#x1f4f1;终端只能纯文本交互的前提下&#xff0c;优雅展示 markdown 文档中的图片。这也许比问题本身还要棘手&#x1f604;。…...

KubeVela可持续测试应用部署之Mock基础设施

Mock接口是我们常用的功能测试方案,有时候依赖的接口未开发完成或者依赖的第三方接口不提供测试环境等,只有Mock才能跑通流程。 我们基于KubeVela开发的云原生应用交付平台,提供如初始化基础设施导入、中间件部署共用基础设施等相关能力的测试,需要依赖基础设施。虽然terr…...

代理IP、Socks5代理与网络工程:解析技术世界的无限可能

在当今数字化的世界中&#xff0c;网络工程师不仅需要保证网络的稳定性&#xff0c;还要应对多样的技术挑战。代理IP和Socks5代理技术已经成为网络工程师工具箱中不可或缺的利器&#xff0c;在跨界电商、爬虫、出海、网络安全、游戏等领域发挥关键作用。本文将深入探讨这两项技…...

OpenCV级联分类器识别车辆实践笔记

1. OpenCV 级联分类器的基本原理 基于Haar特征的级联分类器的目标检测是Paul Viola和Michael Jones在2001年的论文中提出的一种有效的目标检测方法。这是一种基于机器学习的方法&#xff0c;从大量的正面和负面图像中训练级联函数。然后用它来检测其他图像中的物体。 Haar特征…...

VS编译的时候不生成Release文件夹

方法描述&#xff1a; Build>Configuration Manager>Release 编译》配置管理》选择发布版本 再编译就有了 具体操作过程 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 特此记录 anlog 2023年10月12日...

14.2 Socket 反向远程命令行

在本节&#xff0c;我们将继续深入探讨套接字通信技术&#xff0c;并介绍一种常见的用法&#xff0c;实现反向远程命令执行功能。对于安全从业者而言&#xff0c;经常需要在远程主机上执行命令并获取执行结果。本节将介绍如何利用 _popen() 函数来启动命令行进程&#xff0c;并…...

PCL点云处理之点云重建为Mesh模型并保存到PLY文件 ---方法二 (二百一十一)

PCL点云处理之点云重建为Mesh模型并保存到PLY文件 ---方法二 (二百一十一) 一、算法介绍二、算法实现1.代码2.效果一、算法介绍 离散点云重建为mesh网格模型,并保存到PLY文件中,用于其他软件打开查看,代码非常简短,复制粘贴即可迅速上手使用,具体参数根据自己的点云数据…...

CSS 中::after的妙用(实现在margin中显示内容)

效果图如下&#xff1a; 背景&#xff1a; 如上图&#xff0c;之前只是当纯的写一个参考货架平面图&#xff0c;用作物料系统的在库状态可视化&#xff0c;当完成页面body分成10等份时&#xff0c;货架之间需要有通道&#xff0c;为了实现实际的样式&#xff0c;我给每个等份都…...

SentenceTransformer使用多GPU加速向量化

文章目录 前言代码 前言 当我们需要对大规模的数据向量化以存到向量数据库中时&#xff0c;且服务器上有多个GPU可以支配&#xff0c;我们希望同时利用所有的GPU来并行这一过程&#xff0c;加速向量化。 代码 就几行代码&#xff0c;不废话了 from sentence_transformers i…...

架构师-软件工程习题选择题

架构师-软件工程习题选择题 真题案例题 真题 c 瀑布模型&#xff1a;针对软件需求明确的情况&#xff0c;将前一个阶段做完&#xff0c;才能开始下一个阶段 原型模型&#xff1a;针对需求不明确的情况&#xff0c;快速搭建出系统原型&#xff0c;然后根据系统原型和客户确认需求…...

springboot单独在指定地方输出sql

一般线上项目都是将日志进行关闭&#xff0c;因为mybatis日志打印&#xff0c;时间长了&#xff0c;会占用大量的内存&#xff0c;如果我想在我指定的地方进行打印sql情况&#xff0c;怎么玩呢&#xff01; 下面这个场景&#xff1a; 某天线上的项目出bug了&#xff0c;日志打印…...

gpio内部结构(一)

一&#xff0c;GPIO内部结构 1&#xff0c;保护二极管 * 引脚内部加上这两个保护二级管可以防止引脚外部过高或过低的电压输入。 * 当引脚电压高于 VDD_FT 或 VDD 时&#xff0c;上方的二极管导通吸收这个高电压。 * 当引脚电压低于 VSS 时&#xff0c;下方的二极管导通&…...

【C++14保姆级教程】变量模板,Labmda泛型

文章目录 前言一、变量模板&#xff08;Variable Templates&#xff09;1.1 变量模板是什么1.2 泛型大概使用1.3 示例代码11.4 示例代码21.5 示例代码3 二、Lambda泛型&#xff08;Lambda Generics&#xff09;2.1 Lambda表达式泛型是什么&#xff1f;2.2 函数原型怎么写&#…...

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 …...

Vue之VueX知识探索(一起了解关于VueX的新世界)

目录 前言 一、VueX简介 1. 什么是VueX 2. VueX的作用及重要性 3. VueX的应用场景 二、VueX的使用准备工作 1. 下载安装VueX 2. vuex获取值以及改变值 2.1 创建所需示例 2.2 将创建好的.vue文件页面显示 2.3 创建VueX的相关文件 2.4 配置VueX四个js文件 2.5 加载到vue示…...

提升吃鸡战斗力,分享顶级作战干货!

大家好&#xff01;作为一名吃鸡玩家&#xff0c;你是否也希望提高自己的游戏战斗力&#xff1f;在这里&#xff0c;我将为大家分享一些顶级游戏作战干货&#xff0c;以及方便吃鸡作图和查询装备皮肤库存的实用工具。 首先&#xff0c;让我们提到绝地求生作图工具推荐。通过使用…...

【rust】cargo的概念和使用方法

啥是cargo 包管理器 cargo 提供了一系列的工具&#xff0c;从项目的建立、构建到测试、运行直至部署&#xff0c;为 Rust 项目的管理提供尽可能完整的手段&#xff0c;与 Rust 语言及其编译器 rustc 紧密结合。 创建项目 使用cargo创建一个项目&#xff1a; $ cargo new wo…...

MySQL数据库——SQL优化(2)-order by 优化、group by 优化

目录 order by 优化 概述 测试 优化原则 group by 优化 测试 优化原则 order by 优化 概述 MySQL的排序&#xff0c;有两种方式&#xff1a; Using filesort : 通过表的索引或全表扫描&#xff0c;读取满足条件的数据行&#xff0c;然后在排序缓冲区sortbuffer中完成排…...

C++DAY43

#include <iostream>using namespace std;//封装 沙发 类 class Sofa { private:string living; public:Sofa(){cout << "沙发的无参构造函数" << endl;}Sofa(string l):living(l){cout << "沙发的有参构造函数" << endl;}v…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...