【算法刷题之哈希表篇(1)】
目录
- 1.哈希表基础理论
- 2.leetcode-242. 有效的字母异位词
- (1)方法一:排序
- (2)方法二:哈希表
- 3.leetcode-349. 两个数组的交集
- (1)方法一:哈希表
- (2)方法二:排序 + 双指针
- 3.leetcode-202. 快乐数
- (1)方法一:快慢指针
- (2)方法二:哈希表
- 4.leetcode-1. 两数之和
1.哈希表基础理论
哈希表是根据关键码的值而直接进行访问的数据结构。
哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素,如下图所示:
那么哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里。
例如要查询一个名字是否在这所学校里。
要枚举的话时间复杂度是O(n),但如果使用哈希表的话, 只需要O(1)就可以做到。
我们只需要初始化把这所学校里学生的名字都存在哈希表里,在查询的时候通过索引直接就可以知道这位同学在不在这所学校里了。
将学生姓名映射到哈希表上就涉及到了hash function ,也就是哈希函数。
哈希函数
哈希函数,把学生的姓名直接映射为哈希表上的索引,然后就可以通过查询索引下标快速知道这位同学是否在这所学校里了。
哈希函数如下图所示,通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。
常见的三种哈希结构
当我们想使用哈希法来解决问题的时候,我们一般会选择如下三种数据结构。
数组
set (集合)
map(映射)
(可以去看看我的stl详解,其中有详细讲解)
2.leetcode-242. 有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
(1)方法一:排序
t 是 s 的异位词等价于「两个字符串排序后相等」。因此我们可以对字符串 s 和 t 分别排序,看排序后的字符串是否相等即可判断。此外,如果 s 和 t的长度不同,t 必然不是 s 的异位词。
class Solution {
public:bool isAnagram(string s, string t) {if(s.size()!=t.size()){return false;}sort(s.begin(),s.end());sort(t.begin(),t.end());return s==t;}
};
(2)方法二:哈希表
t 是 s 的异位词等价于「两个字符串中字符出现的种类和次数均相等」。由于字符串只包含 26个小写字母,因此我们可以维护一个长度为 26 的频次数组 table,先遍历记录字符串 s 中字符出现的频次,然后遍历字符串 t,减去 table中对应的频次,如果出现 table[i]<0,则说明 t 包含一个不在 s 中的额外字符,返回 false 即可。
class Solution {
public:bool isAnagram(string s, string t) {if (s.length() != t.length()) {return false;}vector<int> table(26, 0);for (auto& ch: s) {table[ch - 'a']++;}for (auto& ch: t) {table[ch - 'a']--;if (table[ch - 'a'] < 0) {return false;}}return true;}
};
3.leetcode-349. 两个数组的交集
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
(1)方法一:哈希表
计算两个数组的交集,直观的方法是遍历数组 nums1,对于其中的每个元素,遍历数组 nums2 判断该元素是否在数组 nums2 中,如果存在,则将该元素添加到返回值。假设数组 nums1 和 nums2 的长度分别是 m 和 n,则遍历数组 nums1 需要 O(m)的时间,判断 nums1 中的每个元素是否在数组 nums2 中需要 O(n) 的时间,因此总时间复杂度是 O(mn)。
如果使用哈希集合存储元素,则可以在 O(1) 的时间内判断一个元素是否在集合中,从而降低时间复杂度。
class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> set1, set2;for (auto& num : nums1) {set1.insert(num);}for (auto& num : nums2) {set2.insert(num);}return getIntersection(set1, set2);}vector<int> getIntersection(unordered_set<int>& set1, unordered_set<int>& set2) {vector<int> intersection;for (auto& num : set1) {if (set2.count(num)) {intersection.push_back(num);}}return intersection;}
};
(2)方法二:排序 + 双指针
1.首先对两个数组进行排序,然后使用两个指针遍历两个数组。
2.可以预见的是加入答案的数组的元素一定是递增的
3.初始时,两个指针分别指向两个数组的头部。每次比较两个指针指向的两个数组中的数字,如果两个数字不相等,则将指向较小数字的指针右移一位。
class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {sort(nums1.begin(), nums1.end());sort(nums2.begin(), nums2.end());int length1 = nums1.size(), length2 = nums2.size();int index1 = 0, index2 = 0;vector<int> intersection;while (index1 < length1 && index2 < length2) {int num1 = nums1[index1], num2 = nums2[index2];if (num1 == num2) {// 保证加入元素的唯一性if (!intersection.size() || num1 != intersection.back()) {intersection.push_back(num1);}index1++;index2++;} else if (num1 < num2) {index1++;} else {index2++;}}return intersection;}
};
3.leetcode-202. 快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
(1)方法一:快慢指针
如图所示:如果不是快乐数也会进入循环,所以用快慢指针来判断,如果会相遇,且相遇时不是1,则不是快乐数。
class Solution {
public:int bitSquareSum(int n) {int sum = 0;while(n > 0){int bit = n % 10;sum += bit * bit;n = n / 10;}return sum;}bool isHappy(int n) {int slow = n, fast = n;do{slow = bitSquareSum(slow);fast = bitSquareSum(fast);fast = bitSquareSum(fast);}while(slow != fast);return slow == 1;}
};
(2)方法二:哈希表
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!
正如:关于哈希表,你该了解这些! (opens new window)中所说,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。判断sum是否重复出现就可以使用unordered_set。
class Solution {
public:int GetSum(int n){int sum=0;while(n>0){sum+=(n%10)*(n%10);n=n/10;}return sum;}bool isHappy(int n) {unordered_set<int> set;while(1){int sum=GetSum(n);if(sum==1){return true;}else if(set.count(sum)){return false;}else{set.insert(sum);}n=sum;} }
};
4.leetcode-1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
map中key和value分别表示什么。
这道题 我们需要 给出一个元素,判断这个元素是否出现过,如果出现过,返回这个元素的下标。
那么判断元素是否出现,这个元素就要作为key,所以数组中的元素作为key,有key对应的就是value,value用来存下标。
所以 map中的存储结构为 {key:数据元素,value:数组元素对应的下标}。
在遍历数组的时候,只需要向map去查询是否有和目前遍历元素匹配的数值,如果有,就找到的匹配对,如果没有,就把目前遍历的元素放进map中,因为map存放的就是我们访问过的元素。
class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {unordered_map<int,int> map;for(int i=0;i<nums.size();++i){auto iter=map.find(target-nums[i]);if(iter!=map.end()){return {iter->second,i};}else{map.insert(pair<int,int> {nums[i],i});}}return {};}
};
相关文章:

【算法刷题之哈希表篇(1)】
目录 1.哈希表基础理论2.leetcode-242. 有效的字母异位词(1)方法一:排序(2)方法二:哈希表 3.leetcode-349. 两个数组的交集(1)方法一:哈希表(2)方…...

uni-app 打包生成签名Sha1
Android平台打包发布apk应用,需要使用数字证书(.keystore文件)进行签名,用于表明开发者身份。 可以使用JRE环境中的keytool命令生成。以下是windows平台生成证书的方法: 安装JRE环境(推荐使用JRE8环境&am…...
【Django】Django创建一个文件下载服务
当使用Django创建一个下载服务时,您可以设置一个视图来处理文件下载请求,并根据您的需求提供文件下载链接。以下是一个简单的示例,演示如何在Django中实现基本的文件下载服务: 创建Django项目和应用: 首先,…...

Navicat for Mysql 显示 emoji 表情符号乱码问题 — 其它乱码情况都可参考
系统环境: 操作系统:MAC OS 10.11.6 MySQL:Server version: 5.6.21 MySQL Community Server (GPL) Navicat for MySQL: version 9.3.1 - standard 1、问题发现 在客户端执行用户注册,用户名包括 emoji 表情符号,注册完…...

《数字图像处理-OpenCV/Python》连载(2)目录
《数字图像处理-OpenCV/Python》连载(2)目录 本书京东优惠购书链接:https://item.jd.com/14098452.html 本书CSDN独家连载专栏:https://blog.csdn.net/youcans/category_12418787.html 第一部分 OpenCV-Python的基本操作 第1章 …...
Go学习-Day4
文章目录 Go学习-Day4函数值传递,引用传递常用的函数 异常处理数组Slice切片 Go学习-Day4 个人博客:CSDN博客 函数 值传递,引用传递 值传递直接拷贝值,一般是基本数据类型,数组,结构体也是引用传递传递…...
将el-dialog封装成函数调用
1、 使用Vue实例化方法 // MyDialog.js import Vue from vue export const openFormDialog function ({ props {}, events {} }) {const vm new Vue({data () {return {form: {}}},render () {return (<el-dialogvisible{true}{...{ props }}{...{ on: events }}onClos…...

Windows10批处理命令行设置环境变量笔记,无需重新安装python与chrome
近期,工作中经常安装、部署python生产、开发环境,比较麻烦,也没有心情去优化。突然,我的电脑崩溃了,在重新安装电脑的过程中,保留了原来的安装软件(有的没有放在系统盘中)࿰…...
统计学补充概念07-比较树
概念 在层次聚类中,聚类结果可以以树状结构表示,通常称为树状图(Dendrogram)。树状图展示了数据点如何被合并或分裂以形成聚类的层次结构。通过观察树状图,可以更直观地理解数据点之间的相似性和关系。 在比较树状图…...
设计原则 --《设计模式之美》总结篇
本文是阅读《设计模式之美》的总结和心得,跳过了书中对面试和工作用处不大或不多的知识点,总结总共分为三章,分别是面对对象编程范式、设计原则和设计模式。 设计模式是代码设计时的一些经验总结。相比于设计模式,设计原则更抽象。…...

Day16-蜗牛影城后端开发
蜗牛影城后端开发 一 多表关联查询 电影集合movie的type(类别)字段关联到电影类别movieType表的_id(主键) 二 蜗牛影城后端开发 1 数据的导入导出 2 用户模块 UserModel.js //导入mongoose,并解构出Schema(类)和model(对象) const {Schema,model} =...

axios / fetch 实现 stream 流式请求
axios 是一个支持node端和浏览器端的易用、简洁且高效的http库。本文主要介绍 axios 如何实现 stream 流式请求,注意这里需要区分 node 环境和浏览器环境。 一、node端 代码演示: const axios require(axios);axios({method: get,url: http://tiven.c…...

Pytorch学习:torchvison.transforms常用包(ToTensor、Resize、Compose和RandomCrop)
torchvision.transforms常用包 1. torchvision.transforms.ToTensor2. torchvision.transforms.Resize3. torchvision.transforms.Compose4. torchvision.transforms.Normalize5. torchvision.transforms.RandomCrop 1. torchvision.transforms.ToTensor 将PIL Image或ndarray…...

算法通关村十二关 | 字符串转换
1. 转换小写字母 LeetCode709:给你一个字符串s,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。 每个字母都是有确定的ASCII的,可以根据码表操作子字符串,常见的ASCII范围是: a-z: 97-122, …...

前端进阶Html+css09----BFC模型
1.什么是BFC模型 全称是:Block formatting context(块级格式化上下文),是一个独立的布局环境,不受外界的影响。 2.FC,BFC,IFC 元素在标准流里都属于一个FC(Formatting Context)。 块级元素的布…...

重排链表(C语言)
题目: 示例: 思路: 这题我们将使用栈解决这个问题,利用栈先进后出的特点,从链表的中间位置进行入栈,寻找链表的中间位置参考:删除链表的中间节点,之后从头开始进行连接。 本题使用…...

el-table动态合并单元格
el-table使用这个方法合并单元格,:span-method“hbcell” <el-table size"small" :data"table.data" border empty-text"暂无数据" :cell-style"cellStyle" :header-cell-style"tableHeaderColor":span-meth…...
html元素
文章目录 html基本结构属性语义化为什么要语义化 示例head中属性样式一些概念块级元素与行级元素空白折叠 html编程没有css的html显示逻辑 html基本结构 html基本单元就是元素,每个元素有标记和属性,如: <a href"...">www&…...

push github
一、生成密钥 打开git bash执行下面指令,Enter下一步Enter下一步..生成ssh key 密钥; ssh-keygen -t rsa 二、 复制公共密钥到git hub 登录github,在选项setting >> SSH and GPG key >> add new ssh添加刚才的公钥地址即可 验证…...

iFluor 594 Styramide是一种荧光染料,常用于生物分子标记和成像
试剂 | 基础知识概述(部分): 中文名称:Alexa Fluor 594酪Styramide 分子量:1341.71 胺的优异替代品 100 Slides 英文名称:iFluor 594 Ex (nm):588 Em (nm):604 规格标准:1g&am…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...