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

LeetCode 热题100之哈希

1.两数之和

在这里插入图片描述
思路分析1(暴力法)

  • 双重循环枚举满足num[i] + nums[j] = = target的索引,刚开始不知道如何返回一对索引。后来知道可以直接通过return {i,j}返回索引;
  • 注意:j应该从i+1处开始,避免使用两次相同的元素;
  • 如果没有找到,则需要返回空return{};
  • 时间复杂度: o ( N 2 ) , o(N^2), o(N2),其中N是数组中的元素数量。最坏情况下数组中任意两个数都要被匹配一次;

具体实现代码(详解版):

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {int l = nums.size(); // 获取数组的长度// 外层循环遍历数组中的每个元素for (int i = 0; i < l; i++) {// 内层循环从下一个元素开始遍历for (int j = i + 1; j < l; j++) {// 检查当前两个元素的和是否等于目标值if (nums[i] + nums[j] == target) {// 如果找到了,返回这两个元素的索引return {i, j};}}}// 如果没有找到满足条件的元素,返回空的 vectorreturn {};}
};

思路分析2(哈希表优化)

  • 遍历数组:对每个元素 nums[i],计算它的补数 target - nums[i];
  • 查找补数:使用 hashtable.find() 方法检查补数是否已存在于哈希表中;
  • 返回索引:如果找到了补数,就返回补数的索引和当前索引i;
  • 更新哈希表:如果未找到补数,则将当前元素及其索引存入哈希表

样例模拟:

对于 nums = [2, 7, 11, 15] 和 target = 9,我们使用twoSum 函数来找到两个数的索引,使它们的和等于目标值。
1.第一轮迭代(i= 0)

  • 当前元素 nums[0] = 2,补数为 9 - 2 = 7;
  • 哈希表中没有 7,所以将 2 存入哈希表:hashtable[2] = 0;

2.第二轮迭代(i =1):

  • 当前元素 nums[1] = 7,补数为 9 - 7 = 2。
  • 在哈希表中找到 2,其索引为 0;
  • 返回 {0, 1},表示 nums[0] 和 nums[1] 的和等于 9。

具体实现代码(详解版):

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int, int> hashtable; // 创建哈希表,存储数字及其索引// 遍历数组中的每个元素for (int i = 0; i < nums.size(); i++) {// 计算当前数字的补数int complement = target - nums[i];// 在哈希表中查找补数auto it = hashtable.find(complement);if (it != hashtable.end()) {// 如果找到了补数,返回其索引和当前索引return {it->second, i};}// 将当前数字及其索引存入哈希表hashtable[nums[i]] = i;}// 如果没有找到,返回空的 vectorreturn {};}
};

2.字母异位词分组

在这里插入图片描述
思路分析1(字母排序)

  • 理解字母异位词:两个字符串互为字母异位词,当且仅当两个字符串包含的字母相同。
    在这里插入图片描述
  • 需要根据特征进行归类,就应该利用哈希表;
  • 由于互为字母异位词的两个字符串包含的字母相同,因此对两个字符串分别进行排序之后得到的字符串一定是相同的,故可以将排序之后的字符串作为哈希表的键,哈希表的值为一组字母异位词列表。
    • 哈希表:使用 unordered_map 来存储排序后的字符串作为键,原字符串作为值的列表。
    • 字符串排序:通过排序将字母异位词归为同一键。
    • 结果构造:将哈希表中的每个值(异位词组)添加到结果向量中。

具体实现代码(详解版):

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {unordered_map<string, vector<string>> mp; // 哈希表,存储异位词组// 遍历每个字符串for (string& str : strs) {string key = str; // 复制当前字符串sort(key.begin(), key.end()); // 将字符串排序,作为哈希表的键mp[key].push_back(str); // 将原字符串加入对应的组}vector<vector<string>> ans; // 存储结果for (auto it = mp.begin(); it != mp.end(); ++it) {ans.push_back(it->second); // 将每组异位词添加到结果中}return ans; // 返回结果}
};

复杂度分析:

  • 时间复杂度:O(nklogk),其中 n 是 strs 中的字符串的数量,k 是 strs 中的字符串的的最大长度。需要遍历 n 个字符串,对于每个字符串,需要 O(klogk) 的时间进行排序以及 O(1) 的时间更新哈希表,因此总时间复杂度是 O(nklogk)。

3.128最长连续序列

在这里插入图片描述
思路分析1(先排序,虽然不符合 O ( n ) O(n) O(n)的时间复杂度吗,但是是最快的)

  • 先对数组进行排序;
  • 然后判断是否是连续序列
    • 如果差1,即是连续的数字,更新最长序列长度
    • 如果它们相等(重复),则可以忽略,不需要修改 mx
  • 否则,说明当前数字与之前的连续序列断开了。需要重置当前序列长度 mx 为 1,因为当前数字本身可以视为新的序列的开始。

具体实现代码(详解版)

class Solution {
public:int longestConsecutive(vector<int>& nums) {if(nums.size() == 0) return 0; // 如果数组为空,返回 0int ans = 1, mx = 1; // 初始化最长序列长度和当前序列长度sort(nums.begin(), nums.end()); // 对数组进行排序for(int i = 1; i < nums.size(); i++) {if(nums[i - 1] + 1 == nums[i]) { // 如果是连续的数字ans = max(ans, ++mx); // 更新最长序列长度}else if(nums[i - 1] == nums[i]) { continue; // 跳过重复数字}else {mx = 1; // 重置当前序列长度}}return ans; // 返回最长连续序列的长度}
};

2.思路分析2:使用哈希集合(优化为 O ( n ) O(n) O(n))

  • 使用 unordered_set 存储输入数组中的所有数字。这允许我们在 O(1) 的时间内快速查找任意数字。

  • 通过 for 循环遍历 numSet 中的每个数字,检查它是否是一个潜在的连续序列的起点。

  • 确定起始点:

    • 通过 numSet.find(num - 1) == numSet.end() 检查当前数字 num 是否是一个连续序列的起点。
    • 如果 num - 1 不在集合中,说明 num 是一个新的序列的开始。
  • 查找连续序列

    • 如果 num 是起始数字,初始化 currentNum 为 num,并将 currentStreak 设为 1(表示当前序列的长度)。
    • 使用 while 循环,查找 currentNum + 1 是否存在于集合中。如果存在,则 currentNum 自增,并且 currentStreak 增加 1,直到没有连续的数字为止。
  • 更新最长序列长度:在每次找到一个完整的连续序列后,将 longestStreak 更新为当前序列长度和已有最长序列长度的较大值。

  • 最后,返回 longestStreak,即数组中最长连续序列的长度

具体实现代码(详解版):

class Solution {
public:int longestConsecutive(vector<int>& nums) {// 使用 unordered_set 存储所有数字unordered_set<int> numSet(nums.begin(), nums.end());int longestStreak = 0;// 遍历每个数字for (int num : numSet) {// 只从未处理的起始数字开始查找//如果 num - 1 不在集合中,说明 num 是一个新的序列的开始。if (numSet.find(num - 1) == numSet.end()) {int currentNum = num;int currentStreak = 1;// 向上查找连续的数字while (numSet.find(currentNum + 1) != numSet.end()) {currentNum++;currentStreak++;}// 更新最长序列长度longestStreak = max(longestStreak, currentStreak);}}return longestStreak; // 返回最长连续序列的长度}
};

在这里插入图片描述
这是两种算法的通过时间,使用算法1的竟然还快一点~(hhhh)

总结:哈希表(集合)常常用于解决与查找、计数或分组相关的问题,在数据结构和算法中广泛应用,如实现字典、集合等。哈希表是一种高效且灵活的数据结构,适合于多种场景,尤其是当需要快速查找、插入和删除时。理解其原理和使用方式可以帮助解决许多实际问题。

相关文章:

LeetCode 热题100之哈希

1.两数之和 思路分析1&#xff08;暴力法&#xff09; 双重循环枚举满足num[i] nums[j] target的索引&#xff0c;刚开始不知道如何返回一对索引。后来知道可以直接通过return {i,j}返回索引&#xff1b;注意&#xff1a;j应该从i1处开始&#xff0c;避免使用两次相同的元素…...

软工——模块设计(爱啦爱啦)

过程设计的工具 一、程序流程图 程序流程图又称为程序框图&#xff0c;它是历史最悠久、使用最广泛的描述过程设计的方法。 它的主要优点是对控制流程的描绘很直观&#xff0c;便于初学者掌握。 程序流程图历史悠久&#xff0c;至今仍在广泛使用着。 程序流程图的主要缺点&a…...

Xmind一款极简思维导图和头脑风暴软件,支持PC和移动端,Xmind 2024.10.01101版本如何升级到Pro版?简单操作,最新可用!

文章目录 Xmind下载安装Xmind免费升级到Pro Xmind 是一款全功能的思维导图和头脑风暴软件&#xff0c;不限制节点和文件数&#xff0c;创新无限&#xff0c;界面纯净简洁无广告&#xff0c;支持PC和移动端&#xff0c;思维导图和大纲视图自由切换&#xff0c;可本地化文档存储&…...

自动化工具:Ansible

目录 一、运维自动化工具有哪些 二、Ansible 概述 1、Ansible 概念 2、Ansible 特点 3、Ansible 工作流程 三、安装部署Ansible 1、环境部署 2、管理节点安装 Ansible 3、查看Ansible相关文件 4、配置主机清单 5、免密管理 ssh-keygen 5.1、测试连通性 5.2、简洁输…...

我是类(最终版)

文章目录 再看构造函数类型转换static静态成员友元内部类匿名对象对象拷贝时的编译器优化 再看构造函数 本标题的目的是解决如下问题&#xff1a;当实现MyQueue时&#xff0c;我们不需要写默认构造函数&#xff0c;因为编译器会调用Stack的默认构造&#xff0c;但是&#xff0…...

详解ip route

ip route命令用于查看 Linux 系统中的路由表信息。 路由表包含的主要信息 目标网络地址&#xff08;Destination&#xff09; 显示网络的目标地址&#xff0c;可以是一个具体的网络地址&#xff08;如192.168.1.0/24&#xff09;&#xff0c;也可以是一个默认网络&#xff08;…...

OpenGL进阶系列04 - OpenGL 点精灵

一:概述 OpenGL 点精灵是一种渲染技术,用于在3D场景中渲染小的、可缩放的点。它们通常用于表示粒子效果、光源或其他小物体。点精灵会根据视图和投影矩阵自动调整大小,使其始终在屏幕上保持一致的视觉效果。实现时,点精灵通常通过使用纹理和适当的着色器来增加视觉效果。 …...

VSCode按ctrl与鼠标左键无法实现跳转的解决办法

vscode编译环境老是出问题&#xff0c;下面介绍两种解决方法 需要提前配置好代码编译需要的库以及编译器位置等等。 ctrlshiftp,输入 >C/C配置&#xff08;JSON&#xff09; 打开生成的c_cpp_properties.json {"configurations": [{"name": "Li…...

U盘数据丢失不用慌,这4个工具可以帮你恢复。

因为将大量的数据存到U盘里面很方便&#xff0c;所以U盘使用也很广泛。但是里面的数据丢失想必很多朋友都碰到过&#xff0c;不过现在有很多方法都可以帮助大家将数据回顾回来。这里我便筛选了几款比较好的数据恢复工具&#xff0c;在这里跟大家分享。 1、福昕U盘恢复软件 直通…...

如何在Ubuntu上挂载一块硬盘:详解方案与实操步骤【小白无坑版】

如何在Ubuntu上挂载一块硬盘&#xff1a;详解方案与实操步骤 一、引言 在日常的开发或使用中&#xff0c;我们经常会遇到这样的场景&#xff1a;系统硬盘空间不足&#xff0c;需要额外挂载一块硬盘以扩展存储&#xff1b;或者我们需要将一块新硬盘用于专门存储数据或备份项目…...

【JAVA】第三张_Eclipse下载、安装、汉化

简介 Eclipse是一种流行的集成开发环境&#xff08;IDE&#xff09;&#xff0c;可用于开发各种编程语言&#xff0c;包括Java、C、Python等。它最初由IBM公司开发&#xff0c;后来被Eclipse Foundation接手并成为一个开源项目。 Eclipse提供了一个功能强大的开发平台&#x…...

go-zero系列-限流(并发控制)及hey压测

参考地址&#xff1a; go-zero系列-限流(并发控制)&#xff1a;https://go-zero.dev/docs/tutorials/service/governance/limiter hey地址&#xff1a;https://github.com/rakyll/hey1、压测工具hey下载安装&#xff1a; 会安装到GOPATH/bin目录下 go install github.com/ra…...

Electron-(三)网页报错处理与请求监听

在前端开发中&#xff0c;Electron 是一个强大的框架&#xff0c;它允许我们使用 Web 技术构建跨平台的桌面应用程序。在开发过程中&#xff0c;及时处理网页报错和监听请求是非常重要的环节。本文将详细介绍 Electron 中网页报错的日志记录、webContents 的监听事件以及如何监…...

银河麒麟(debian)下安装postgresql、postgis

1、安装postgresql、postgis sudo apt update sudo apt install postgresql postgresql-contrib sudo apt install postgis postgresql-12-postgis-32、创建一个使用postgis的数据库 sudo -i -u postgres #postgres管理员用户createdb gisdb #创建新的gisdb数据库 psql -d gi…...

【已解决】【Hadoop】 Shell命令易错点及解决方法

Hadoop是一个强大的分布式系统&#xff0c;用于处理大规模数据集。在使用Hadoop的过程中&#xff0c;熟练掌握其Shell命令是必不可少的。本文将介绍几个常用的Hadoop Shell命令&#xff0c;并总结一些常见的操作错误及其解决方法。 Hadoop Shell命令简介 Hadoop提供了多种She…...

ST7789读取ID错误新思路(以STC32G为例)

1.前言 前两天刚把ST7789写入搞定&#xff0c;这两天想折腾一下读取。最开始是读ID&#xff0c;先是用厂家送的程序&#xff0c;程序里面用的是模拟I8080协议&#xff0c;一切正常。后来我用STC32G的内置LCM模块&#xff0c;发现读取不出来。更神奇的是ID读不出来&#xff0c;…...

【MySQL】入门篇—基本数据类型:使用ORDER BY进行排序

MySQL作为一种流行的关系数据库管理系统&#xff0c;提供了强大的数据查询功能&#xff0c;其中ORDER BY子句用于对查询结果进行排序。排序可以帮助用户更直观地查看数据&#xff0c;发现趋势或异常&#xff0c;尤其在处理大量数据时尤为重要。 应用场景&#xff1a; 用户管理…...

java线程池bug的一些思考

科学需要对前人的怀疑&#xff0c;对权威的怀疑。 但是上学的时候&#xff0c;我们也需要去理解课本。 现在网上充斥了“java 线程池的缺点”这一观点。分析了一下线程池的工作原理&#xff0c;确实也存在这些问题。 Java线程池工作原理。核心线程数&#xff0c;最大线程数&…...

深入解析浮动布局及其在现代Web开发中的应用与替代(浮动的概念及应用、如何清除浮动、使用Flex布局和Grid布局的区别、使用`float`布局的历史和现状)

文章目录 1. 引言2. 浮动的概念及应用3. 如何清除浮动4. 使用Flex布局和Grid布局的区别5. 使用float布局的历史和现状6. 综合案例展示7. 结论8. 建议 1. 引言 在CSS布局的历史中&#xff0c;float属性曾是网页布局的主要工具之一。然而&#xff0c;随着现代布局技术&#xff0…...

WPF基础权限系统

一.开发环境 VisualStudio 2022NET SDK 8.0Prism 版本 8.1.97Sqlite 二. 功能介绍 WPF 基础权限系统&#xff0c;是一个支持前后端分离设计的 客户端(C/S)项目&#xff0c;该示例项目前端xaml使用UI库 &#xff0c;Material Design Themes UI 来构建用户界面&#xff0c;确保…...

无机布防火卷帘门报价透明,包工包料,一次说清所有费用

很多客户在选购无机布防火卷帘门时&#xff0c;最关心实际成交价格&#xff0c;也担心报价不清晰&#xff0c;后期产生各类额外支出。行业内产品定价参差不齐&#xff0c;选材做工不同&#xff0c;最终价位自然存在差距&#xff0c;挑选时不能只看表面低价。 &#x1f449; 点击…...

机器学习赋能6G近场通信:从信道估计到波束赋形的智能革命

1. 项目概述&#xff1a;当6G遇见近场&#xff0c;为何机器学习成为破局关键&#xff1f;如果你关注过5G到6G的技术演进路线&#xff0c;会发现一个核心趋势&#xff1a;天线阵列的规模正在从“大规模”走向“极大规模”。这不仅仅是数量的堆砌&#xff0c;更是通信物理原理的一…...

AMLP:基于大语言模型的自动化机器学习势函数构建平台

1. 项目概述&#xff1a;当AI遇见原子模拟&#xff0c;AMLP如何重塑机器学习势函数构建在计算材料科学和化学物理领域&#xff0c;分子动力学模拟是我们窥探微观世界动态行为的“显微镜”。无论是研究新材料的相变过程&#xff0c;还是探索生物大分子的折叠机制&#xff0c;其核…...

智能检索新范式,让AIAgent自主决策,提升RAG效率100%!

市面上的 RAG 系统&#xff0c;不管叫什么名字&#xff0c;本质上只有两种做法&#xff1a; 第一种&#xff0c;一次性检索。把用户的 query 向量化&#xff0c;从语料库里捞出 Top-K 个文档片段&#xff0c;拼成一个大 prompt 塞给模型。GraphRAG、HippoRAG、LightRAG 都属于…...

DeepSeek系统设计辅助:如何在48小时内完成可审计、可回滚、可压测的AI服务架构图?

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek系统设计辅助 DeepSeek系统设计辅助模块面向架构师与后端工程师&#xff0c;提供模型能力调用、接口契约生成、异步任务编排等核心支撑能力。该模块不替代人工设计决策&#xff0c;而是通过结构…...

收藏必看|2026 版大厂 AI 岗位薪资曝光!普通程序员转型大模型最全指南

深夜收到大厂 HR 好友发来的内部资料&#xff0c;再三叮嘱切勿对外泄露。如今网络信息传播速度极快&#xff0c;这份 2026 年企业 AI 岗真实薪资内幕&#xff0c;也值得给广大程序员、零基础入行小白参考借鉴。 翻看完整薪资台账后&#xff0c;真切感受到当下大模型赛道的薪资差…...

串口通信粘包问题:成因深度解析与项目实战解决方案

在嵌入式开发、工业工控、上位机下位机交互项目中&#xff0c;串口&#xff08;RS232/RS485&#xff09;是最基础、最常用的通信方式。绝大多数开发者都遇到过这样的问题&#xff1a;串口接收的数据偶尔错乱、解析报错、数据拼接异常&#xff0c;单次接收的数据时而半包、时而多…...

毕业设计 yolov11骨折检测医疗辅助系统(源码+论文)

文章目录 0 前言1 项目运行效果2 课题背景2.1 研究背景2.2 国内外研究现状2.3 研究意义 3 设计框架&#xff08;骨折检测系统设计框架说明&#xff09;3.1. 系统架构图3.2. 技术选型3.2.1 核心组件3.2.2 辅助工具 3.3. 核心模块设计3.3.1 YOLO模型训练模块训练流程图关键伪代码…...

GEO生成引擎优化:当AI成为信息分发的主角,品牌如何抢占对话窗口?

当用户不再"搜索-浏览"&#xff0c;而是直接"AI提问-获取答案"&#xff0c;传统SEO的逻辑正在被彻底改写。2026年&#xff0c;GEO&#xff08;Generative Engine Optimization&#xff0c;生成式引擎优化&#xff09;已经从概念走向规模化落地。本文从技术…...

Godot4 2D游戏开发避坑指南:TileMap绘制、节点顺序与相机设置的三个常见问题

Godot4 2D游戏开发避坑指南&#xff1a;TileMap绘制、节点顺序与相机设置的三个常见问题当你第一次用Godot4完成一个2D场景搭建时&#xff0c;那种成就感往往会被几个突如其来的bug瞬间击碎——角色神秘消失、背景纹丝不动、屏幕边缘出现诡异黑边。这些问题看似简单&#xff0c…...