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

【算法刷题之哈希表(2)】

目录

  • 1.leetcode-454. 四数相加 II
  • 2.leetcode-383. 赎金信
    • (1)暴力解法
    • (2)哈希法
  • 3.leetcode-205. 同构字符串
    • (1)哈希法
    • (2)直接对比查找
  • 4.leetcode-128. 最长连续序列
  • 5.总结

1.leetcode-454. 四数相加 II

(1)题目描述
给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
在这里插入图片描述
(2)思路与方法
对于这道题可能首先想到的就是对于四个数组进行循环遍历,但是这种方法的时间复杂度时n^4,不建议使用,所以我们想到两组两组遍历。

本题解题步骤:

1.首先定义 一个unordered_map,key放a和b两数之和,value 放a和b两数之和出现的次数。
2.遍历大A和大B数组,统计两个数组元素之和,和出现的次数,放到map中。
3.定义int变量count,用来统计 a+b+c+d = 0 出现的次数。
4.在遍历大C和大D数组,找到如果 0-(c+d) 在map中出现过的话,就用count把map中key对应的value也就是出现次数统计出来。
5.最后返回统计值 count 就可以了

class Solution {
public:int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {unordered_map<int,int> map;int count=0;for(int a:nums1){for(int b:nums2){map[a+b]++;}}for(int c:nums3){for(int d:nums4){int target=0-c-d;count+=map[target];}}return count;}
};

2.leetcode-383. 赎金信

(1)题目描述
给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。
(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)
在这里插入图片描述

(1)暴力解法

那么第一个思路其实就是暴力枚举了,两层for循环,不断去寻找,代码如下:

class Solution {
public:bool canConstruct(string ransomNote, string magazine) {for (int i = 0; i < magazine.length(); i++) {for (int j = 0; j < ransomNote.length(); j++) {// 在ransomNote中找到和magazine相同的字符if (magazine[i] == ransomNote[j]) {ransomNote.erase(ransomNote.begin() + j); // ransomNote删除这个字符break;}}}// 如果ransomNote为空,则说明magazine的字符可以组成ransomNoteif (ransomNote.length() == 0) {return true;}return false;}
};

(2)哈希法

因为题目所只有小写字母,那可以采用空间换取时间的哈希策略, 用一个长度为26的数组还记录magazine里字母出现的次数。

然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母。

依然是数组在哈希法中的应用。

一些同学可能想,用数组干啥,都用map完事了,其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了。 所以数组更加简单直接有效!

class Solution {
public:bool canConstruct(string ransomNote, string magazine) {vector<int> ans(26,0);int n2=magazine.size();int n1=ransomNote.size();for(auto& a:magazine){ans[a-'a']++;}for(int i=0;i<n1;++i){ans[ransomNote[i]-'a']--;if(ans[ransomNote[i]-'a']<0){return false;}}return true;}
};

3.leetcode-205. 同构字符串

给定两个字符串 s 和 t ,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

在这里插入图片描述

(1)哈希法

需要我们判断 s和 t每个位置上的字符是否都一一对应,即 s 的任意一个字符被 t 中唯一的字符对应,同时 t 的任意一个字符被 s 中唯一的字符对应。这也被称为「双射」的关系。
我们维护两张哈希表,第一张哈希表 s2t 以 s 中字符为键,映射至 t 的字符为值,第二张哈希表 t2s以 t 中字符为键,映射至 s 的字符为值。从左至右遍历两个字符串的字符,不断更新两张哈希表,如果出现冲突,即当前下标 index 对应的字符 s[index] 已经存在映射且不为 t[index]或当前下标 index 对应的字符 t[index] 已经存在映射且不为 s[index]时说明两个字符串无法构成同构,返回 false 。

class Solution {
public:bool isIsomorphic(string s, string t){unordered_map<char,char> map1;unordered_map<char,char> map2;for(int i=0;i<s.size();++i){char x=s[i];char y=t[i];if(map1.count(x)&&map1[x]!=y||map2.count(y)&&map2[y]!=x){return false;}map1[x]=y;map2[y]=x;}return true;}
};

(2)直接对比查找

class Solution {
public:bool isIsomorphic(string s, string t){for(int i=0;i<s.size();++i){if(s.find(s[i])!=t.find(t[i]))return false;}return true;}
};

4.leetcode-128. 最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
在这里插入图片描述

1.创建一个名为 num_set 的无序集合(unordered_set),用于存储 nums 向量中的唯一整数。集合确保消除重复的数字。

2.代码遍历 nums 向量中的每个元素,并将其插入到 num_set 中。

3.将变量 longestStreak 初始化为 0,表示目前为止找到的最长连续子序列的长度。

4.代码遍历 num_set 中的每个元素 num:

如果 num 是连续子序列的起始数字(即 num - 1 不在 num_set 中),则进入循环。

在循环内部,将变量 currentNum 设置为 num,并将 currentStreak 初始化为 1(因为 num 本身就构成长度为 1 的子序列)。

只要 num_set 中存在 currentNum + 1,代码将持续增加 currentNum 和 currentStreak。这个循环计算从 num 开始的连续子序列的长度。

使用 max 函数将 longestStreak 更新为当前 longestStreak 和 currentStreak 的最大值,以确保它保留到目前为止找到的最长子序列的长度。

5.在遍历所有元素后,函数返回 longestStreak,它表示给定向量中最长连续子序列的长度。

class Solution {
public:int longestConsecutive(vector<int>& nums) {unordered_set<int> num_set;for (const int& num : nums) {num_set.insert(num);}int longestStreak = 0;for (const int& num : num_set) {if (!num_set.count(num - 1)) {int currentNum = num;int currentStreak = 1;while (num_set.count(currentNum + 1)) {currentNum += 1;currentStreak += 1;}longestStreak = max(longestStreak, currentStreak);}}return longestStreak;           }
};

5.总结

数组作为哈希表
在242.有效的字母异位词 (opens new window)中,我们提到了数组就是简单的哈希表,但是数组的大小是受限的!

这道题目包含小写字母,那么使用数组来做哈希最合适不过。

在383.赎金信 (opens new window)中同样要求只有小写字母,那么就给我们浓浓的暗示,用数组!

本题和242.有效的字母异位词 (opens new window)很像,242.有效的字母异位词 (opens new window)是求 字符串a 和 字符串b 是否可以相互组成,在383.赎金信 (opens new window)中是求字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。

一些同学可能想,用数组干啥,都用map不就完事了。

上面两道题目用map确实可以,但使用map的空间消耗要比数组大一些,因为map要维护红黑树或者符号表,而且还要做哈希函数的运算。所以数组更加简单直接有效!

set作为哈希表
在349. 两个数组的交集 (opens new window)中我们给出了什么时候用数组就不行了,需要用set。
这道题目没有限制数值的大小,就无法使用数组来做哈希表了。
主要因为如下两点:
数组的大小是有限的,受到系统栈空间(不是数据结构的栈)的限制。
如果数组空间够大,但哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。
map作为哈希表
在1.两数之和 (opens new window)中map正式登场。
来说一说:使用数组和set来做哈希法的局限。
数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。
set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。
map是一种<key, value>的结构,本题可以用key保存数值,用value在保存数值所在的下标。所以使用map最为合适。

本篇我们从哈希表的理论基础到数组、set和map的经典应用,把哈希表的整个全貌完整的呈现给大家。

相关文章:

【算法刷题之哈希表(2)】

目录 1.leetcode-454. 四数相加 II2.leetcode-383. 赎金信&#xff08;1&#xff09;暴力解法&#xff08;2&#xff09;哈希法 3.leetcode-205. 同构字符串&#xff08;1&#xff09;哈希法&#xff08;2&#xff09;直接对比查找 4.leetcode-128. 最长连续序列5.总结 1.leetc…...

如何创建和销售在线健身业务

快速轻松地创建您自己的线上健身网站&#xff01; 越来越多的人在家健身&#xff0c;在线健身业务也随之快速增长。 虽然这个生意很红火&#xff0c;但是真的像看起来那么容易上手吗&#xff1f; 有了MemberPress&#xff0c;确实如此&#xff01; 在这篇文章中&#xff0c…...

使用IIC进行多数据读取测试

IIC系列文章: (1)I2C 接口控制器理论讲解 (2)I2C接口控制设计与实现 (3)I2C连续读写实现 (4)使用IIC进行多数据读取测试 文章目录 前言一、control_RD_req模块二、顶层文件(IIC_control_EEPROM)三、测试文件(control_RD_req_tb)前言 使用已完成的IIC模块,将256个数据写入…...

drools8尝试(加单元测试)

drools8的maven模板项目里没有单元测试, 相比而言drools7有个非常好的test senorios 那就自己弄一个 文件是.http后缀的,写了个简单的例子如下 //测试交通违章 POST http://localhost:8080/Traffic Violation accept: application/json Content-Type: application/json{&q…...

Web3和去中心化:互联网的下一个演化阶段

文章目录 Web3和去中心化的定义Web3&#xff1a;去中心化&#xff1a; 为什么Web3和去中心化如此重要&#xff1f;数据隐私和安全&#xff1a;去中心化的创新&#xff1a;去除中间商&#xff1a; Web3和去中心化的应用领域去中心化金融&#xff08;DeFi&#xff09;&#xff1a…...

stm32 之20.HC-06蓝牙模块

原理图显示使用usart3串口使用的是PB10和PB11引脚 直接配置usart3串口协议 void usart3_init(uint32_t baud) {GPIO_InitTypeDef GPIO_InitStructureure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//端口B硬件时钟打开RCC_AHB1PeriphClockC…...

[技术杂谈]macOS上todesk无法远程操作鼠标键盘

远程到被控Mac后能看到画面&#xff0c;鼠标键盘操作无反应 远程后发现画面显示正常&#xff0c;但是键盘和鼠标的操作没有响应 可能是辅助功能没有勾选ToDesk_Session的权限。 可按以下步骤操作&#xff1a; 1> 在左上角点击苹果图标&#xff0c;选择“系统偏好设置” …...

【C++设计模式】用简单工厂模式实现按汽车重量输出汽车类型

2023年8月24日&#xff0c;周四凌晨 #include<iostream>class CarType{ public:virtual std::string getType()0; };class MiniCar:public CarType{ public:std::string getType() override{return "小型车";}; };class MidSizeCar:public CarType{ public:std…...

【Ubuntu20.04安装Nvidia驱动、CUDA和CUDNN】

Ubuntu20.04安装Nvidia驱动、CUDA和CUDNN 1 Nvidia驱动安装1.1 安装1.2 安装Nvidia可能会遇到的问题1.2.1 NVIDIA 驱动与 Nouveau 驱动不兼容1.2.2 ERROR: Unable to find the development tool cc 2 CUDA安装2.1 下载和安装2.2 配置CUDA环境 3 安装CUDNN4 切换CUDA版本 1 Nvid…...

[Python进阶] 类的设计模式

4.11 设计模式 在Python中&#xff0c;类的设计模式是指一种通用的解决方案或设计模板&#xff0c;针对特定的问题或需求构建类结构&#xff0c;并提供相关的方法和属性。这些设计模式可以帮助开发人员遵循最佳实践、提高代码质量、增强可读性、降低维护成本。 需要注意的是&a…...

设计模式 07 桥接模式

桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型模式 概述 桥接模式是将抽象部分与它的实现部分分离&#xff0c;使它们都可以独立地变化。它是一种对象结构型模式&#xff0c;又称为柄体&#xff08;Handle and Body&#xff09;模式或接口&#xff08;Interface&…...

linux系统(centos、ubuntu、银河麒麟服务、uos、deepin)判断程序是否已安装,通用判断方法:使用所有应用和命令的判断

前言 项目中需要判断linux服务器中是否已经安装了某个服务 方法有很多种&#xff0c;但是很多都不通用&#xff0c; 脚本代码就不容易做成统一的 解决方案 用下面的脚本代码去进行判断 用jdk测试 脚本意思如下&#xff1a; 输入java -version命令&#xff0c;将返回的字…...

机器学习各算法优缺点汇总

链接: (链接: link)...

手把手教你部署Jenkins教程,小白也能学会(多图预警)!

背景 公司的前端、后端构建及部署工作都是人工去做&#xff0c;随着业务扩大&#xff0c;项目迭代速度变快&#xff0c;人员增多&#xff0c;各种问题都暴露出来&#xff0c;将通过一个简单案例分享一下基于Jenkins的前后端自动化工作流搭建的过程&#xff0c;搭建完这套工作流…...

一种IDEA疑难杂症的解决办法

解决办法 重启IDEA 针对于IDEA各种羡慕解析&#xff0c;运行时问题&#xff0c;但是无法通过搜索引擎得到答案的问题请试试此方法。 删除根目录下[.idea]文件夹后重启 此文件夹为idea首次导入项目时根据项目情况自动生成的配置文件。方便idea下次更快的解析项目。但是某些情…...

TikTok小店玩法有哪些?一起来玩转TiKTok!

随着TikTok在海外市场份额不断增加&#xff0c;越来越多卖家选择入驻TikTok跨境小店&#xff0c;但是在入驻之后我们需要知道有哪些主流玩法&#xff0c;才能根据实际情况制定合适的运营方案。接下来小编就给大家介绍一下TikTok小店玩法有哪些&#xff01; 本土模式 这种模式…...

Mongodb 集合插入文档自动生成ObjectId

插入单个文档 Mongodb 使用以下几种方法来插入文档 &#xff0c; Mongodb V5.0 使用 mongosh 客户端&#xff1a; 插入单个文档 db.collection.insertOne() 将单个 文档插入到集合中。 如果该集合当前不存在&#xff0c;则插入操作将创建该集合。 如果文档未指定_id字段&am…...

C# .aspx网页获取RFID读卡器HTTP协议提交的访问文件Request获得卡号、机号,Response回应驱动读卡器显示响声

本示例使用的设备&#xff1a;RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) 服务端代码&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.…...

Kali Linux 2023.3 发布

Offective Security 发布了 Kali Linux 2023.3&#xff0c;这是其渗透测试和数字取证平台的最新版本。 Kali Linux 2023.3 中的新工具 除了对当前工具的更新之外&#xff0c;新版本的 Kali 通常还会引入新的工具。 这次&#xff0c;他们是&#xff1a; Calico – 云原生网络…...

如何用Python实现从pdf文件精准抓取数据生成数据库!

要从PDF文件中提取数据并生成数据库&#xff0c;你可以使用Python中的一些库和工具来实现。 1、安装必要的库&#xff1a;确保已安装所需的库。除了之前提到的PyPDF2、pdfminer.six和pdftotext之外&#xff0c;你可能还需要其他的库来处理提取的数据和数据库操作。例如&#x…...

黑客马拉松(Hackathon)文化:是创新工场,还是疲劳表演?

在软件工程的世界里&#xff0c;我们测试人常常站在产品交付的最后一道防线上&#xff0c;习惯了在严谨的流程、详尽的用例和稳定的环境中寻找缺陷。而黑客马拉松&#xff0c;这个充满激情、混乱与极限编程的代名词&#xff0c;对我们来说&#xff0c;既像是一个遥不可及的极客…...

公考备考提分真相:从学员视角解析粉笔讲练测评闭环教学体系

引言在公务员考试备考赛道中&#xff0c;无数考生都面临同一个核心困惑&#xff1a;花费时间和金钱报名培训机构&#xff0c;究竟能不能实现有效提分&#xff1f;不少备考者有过备考失利的经历&#xff0c;也踩过传统公考培训的诸多坑。很多传统课程老师讲课条理清晰、内容丰富…...

长期使用Taotoken Token Plan套餐带来的成本控制感受

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 长期使用Taotoken Token Plan套餐带来的成本控制感受 1. 从按需付费到预算规划 对于个人开发者或小型团队而言&#xff0c;大模型…...

ASML如何用“先买单后上菜”模式改写半导体设备研发规则

1. 从“被放鸽子”到“先买单后上菜”&#xff1a;ASML的450毫米晶圆博弈论在半导体这个以“摩尔定律”为信仰的行业里&#xff0c;每一次技术节点的跃进都伴随着天文数字的投入和巨大的商业风险。对于设备商而言&#xff0c;最怕的不是技术难题&#xff0c;而是倾尽所有研发出…...

自然语言编写嵌入式软件之点亮LED灯

要实现的功能&#xff1a; 控制LED以10HZ的频率闪烁 传统实现过程&#xff1a;学C语言&#xff0c;看数据手册了解MCU&#xff0c;学教程&#xff0c;copy代码&#xff0c;学编译调试环境&#xff0c;学仿真&#xff0c;学用仪器测量 自然语言编程实现过程&#xff1a; 搭建…...

工业控制系统安全实践:基于ISA-62443-3-3标准的OT/IT融合指南

1. 项目概述&#xff1a;当工业安全遇上新标准在工业自动化领域摸爬滚打了十几年&#xff0c;我见过太多因为安全标准“两张皮”而引发的头疼事。一边是负责生产线的工控工程师&#xff0c;他们的核心信条是“稳定压倒一切”&#xff0c;任何可能影响PLC运行周期、导致电机意外…...

深入Windows内核的“心脏”:通过WRK源码理解ntoskrnl.exe与HAL的协作机制

深入Windows内核的“心脏”&#xff1a;通过WRK源码理解ntoskrnl.exe与HAL的协作机制 在计算机科学领域&#xff0c;操作系统内核堪称最复杂的软件工程之一。作为Windows操作系统的核心&#xff0c;ntoskrnl.exe与硬件抽象层(HAL)的协作机制长期以来都是开发者们津津乐道的话题…...

告别混乱XML:Notepad++插件一键美化与智能纠错实战

1. 为什么我们需要XML格式化工具&#xff1f; 作为一个常年和XML打交道的开发者&#xff0c;我太清楚那种打开一个几千行XML文件时的绝望了——所有标签挤在一起&#xff0c;缩进混乱得像被猫抓过的毛线球&#xff0c;想找个节点得用CtrlF来回搜三遍。更可怕的是&#xff0c;有…...

实测:2026 年国内直连 AI 一站式平台,聊天 / 绘画 / 论文 / 视频全搞定,不用翻墙不花冤枉钱

最近 AI 圈真的太卷了。ChatGPT 5.4、Gemini 3.1、Claude Code 轮番上新&#xff0c;多模态、长文本、代码 Auto Mode 一个比一个强。但普通用户想用明白&#xff0c;真的太折腾。先说说我踩过的三大坑&#xff0c;句句大实话网络糟心到崩溃官网打不开、地区不可用、加载转圈、…...

用OpenMV4 H7 PLUS做个智能分拣小车:颜色识别实战项目从硬件选型到代码集成

智能分拣小车实战&#xff1a;OpenMV4 H7 PLUS颜色识别与嵌入式系统集成 在创客竞赛和毕业设计中&#xff0c;智能分拣系统一直是热门选题。传统方案往往面临识别精度不足、响应延迟高或硬件兼容性差等问题。OpenMV4 H7 PLUS凭借其强大的图像处理能力和丰富的硬件接口&#xff…...