油画网站模板/陕西百度代理公司
1. 哈希表
文章目录
- 1. 哈希表
- 写在前面
- 1.1 理论基础
- 1.2 有效的字母异位词
- 1.3 两个数组的交集
- 1.4 快乐数
- 1.5 两数之和
- 1.6 四数相加||
- 1.7 赎金信
- 1.8 三数之和(哈希法梦碎的地方)
- 1.9 四数之和
- Reference
写在前面
本系列笔记主要作为笔者刷题的题解,所用的语言为Python3
,若于您有助,不胜荣幸。
1.1 理论基础
哈希表[hash table]又称为散列表,它是一种通过键key
与值value
的映射关系来实现高效的增删查找操作,具体而言,我们是通过一个键key
来对哈希表进行访问,查询获得其value
。哈希表各种操作效率对比
数组 | 链表 | 哈希表 | |
---|---|---|---|
查找元素 | O ( n ) \mathcal{O}(n) O(n) | O ( n ) \mathcal{O}(n) O(n) | O ( 1 ) \mathcal{O}(1) O(1) |
添加元素 | O ( 1 ) \mathcal{O}(1) O(1) | O ( 1 ) \mathcal{O}(1) O(1) | O ( 1 ) \mathcal{O}(1) O(1) |
删除元素 | O ( n ) \mathcal{O}(n) O(n) | O ( n ) \mathcal{O}(n) O(n) | O ( 1 ) \mathcal{O}(1) O(1) |
在哈希表中进行增删查改的时间复杂度都是 O ( 1 ) \mathcal{O}(1) O(1) ,非常高效。
在哈希表中,我们将表中的每个空位称为桶[bucket],每个桶可以存储一个键值对,因此,查询操作就是找到key
对应的桶,并在桶中获取value
。在哈希表中如何对需要查询的元素进行定位呢?这里使用了一个函数来将key
映射为哈希表中的位置,这个函数被称为hash()
哈希函数,该函数的实现有许多中方式,这里不再展开。
如果哈希函数查询不同的key
,但是出现了相同的返回值这应该怎么办呢?这种情况被称为哈希冲突,针对哈希冲突有多种扩容的方式,这里也不再展开。哈希表其实就是一种牺牲了空间来换取时间的数据结构。
当我们想使用哈希法来解决问题的时候,我们一般会选择如下的三种数据结构:
- 数组
- set(集合)
- map(映射)/ dict(字典)
在python3
中内置的数据结构dict
其实就是一种hash table
。
1.2 有效的字母异位词
给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的字母异位词。
**注意:**若 s
和 t
中每个字符出现的次数都相同,则称 s
和 t
互为字母异位词。
解法一:数组
使用数组我们需要手搓一个hash
函数
class Solution:def isAnagram(self, s: str, t: str) -> bool:hashtable: List = [0] * 26for char in s:hashtable[ord(char) - ord('a')] += 1for char in t:hashtable[ord(char) - ord('a')] -= 1for value in hashtable:if value != 0:return Falsereturn True
其中,python3
内置函数ord()
用于获取字符的 ASCII 码值或 Unicode 码值。将获取到字符的ASCII码与a
的ASCII码相减,这样我们就获取到了在hashtable
中存放的相对应索引,这就是我们手搓的hash
函数。
解法二:使用字典
from collections import defaultdict
class Solution:def isAnagram(self, s: str, t: str) -> bool:hashs: dict = defaultdict(int)hasht: dict = defaultdict(int)for char in s:hashs[char] += 1for char in t:hasht[char] += 1return hashs == hasht
这里需要注意defaultdict
的用法,当defaultdict
首次访问不存在的key
时,会将其的值设置为0
1.3 两个数组的交集
349. 两个数组的交集
给定两个数组 nums1
和 nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
解法一:使用map
from collections import defaultdict
class Solution:def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:res: set = set() # 用set来去重hashtable: dict = defaultdict(int)for n in nums1:hashtable[n] = 1for n in nums2:if hashtable[n] == 1:res.add(n)return list(res)
当我们需要考虑去重的时候,我们通常使用set
数据结构来保存结果,set
不允许有重复的元素存在,利用该特性自动完成去重。
class Solution:def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:res: set = set()hashtable: dict = {}for n in nums1:hashtable[n] = hashtable.get(n, 0) + 1for n in nums2:if hashtable.get(n, 0) != 0:res.add(n)return list(res)
自用内置的dict()
,方法dict.get(key, defaultvalue)
,尝试查询key
的值,如果key
不存在则返回defaultvalue
。
解法二:使用数组
class Solution:def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:res: set = set()hashtable: List = [0]*1001 # 开辟存储空间for n in nums1:hashtable[n - 1] = 1for n in nums2:if hashtable[n - 1] == 1:res.add(n)return list(res)
解法三:python的特性
class Solution:def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:res: List = []for num in nums1:if num in nums2 and num not in res:res.append(num)return res
class Solution:def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:return list(set(nums1) & set(nums2))
1.4 快乐数
202. 快乐数
编写一个算法来判断一个数 n
是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n
是 快乐数 就返回 true
;不是,则返回 false
。
这道题的关键在于无限循环上,如果我们按照常规思维来判断的话,我们不知道需要循环多少次,如果是无限循环的话,我们就无法跳出这个循环,那么应该如何解决呢?重点在于我们可以怎么判断它是否开始循环了,如果这个快乐数的演变过程中,出现了已经出现过的数,那么就表明它已经陷入循环了,那就肯定不是快乐数。所有这就是一个典型的查询过程,我们可以用哈希法来解决。
class Solution:def isHappy(self, n: int) -> bool:seen: set = {1}while n not in seen: # 当n已经出现过则退出循环seen.add(n)n = sum([int(s)**2 for s in str(n)])return n == 1
1.5 两数之和
1. 两数之和
解法一:使用dict作为hash table
class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:record: dict = {}for index, value in enumerate(nums):res: int = target - valueif res in record:return [record[res], index]record[value] = index # 保存新元素一定要放在后面,这样可以防止当前的value和record中的key冲突return []
解法二:使用set作为hash table
class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:record: set = set() # 使用set作为hash tablefor index, value in enumerate(nums):res: int = target - valueif res in record:return [nums.index(res), index]record.add(value)return []
1.6 四数相加||
454. 四数相加 II
给你四个整数数组 nums1
、nums2
、nums3
和 nums4
,数组长度都是 n
,请你计算有多少个元组 (i, j, k, l)
能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
我们将四个数组分别用A,B,C,D来表示,一个具体的思路是,我们先对其中2个数组进行遍历统计其和的出现次数(如a+b)生成一个hash table,然后再遍历剩余的两个数组来进行查找(c+d的负数在其中出现的次数),如果出现了a+b+c+d=0
则符合要求,要求我们需要统计出现的次数,所以我们使用dict
作为哈希表的结构。
为什么是分为两两来进行遍历呢?因为我们分为一个数组和三个数组来进行遍历的话,时间复杂度为 O ( n 3 ) \mathcal{O}(n^3) O(n3),两两遍历的时间复杂度为 O ( n 2 ) \mathcal{O}(n^2) O(n2),这样更优。
class Solution:def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:record: dict = {}count: int = 0for value1 in nums1:for value2 in nums2:record[value1 + value2] = record.get(value1 + value2, 0) + 1for value3 in nums3:for value4 in nums4:count += record.get(-(value3 + value4), 0)return count
1.7 赎金信
383. 赎金信
给你两个字符串:ransomNote
和 magazine
,判断 ransomNote
能不能由 magazine
里面的字符构成。
如果可以,返回 true
;否则返回 false
。
解法一:使用dict
class Solution:def canConstruct(self, ransomNote: str, magazine: str) -> bool:record: dict = {}for char in magazine:record[char] = record.get(char, 0) + 1for char in ransomNote:if char not in record:return Falserecord[char] -= 1for times in record.values():if times < 0:return Falsereturn True
解法二:使用数组
class Solution:def canConstruct(self, ransomNote: str, magazine: str) -> bool:record: List = [0] * 26 # 因为字母一共26个for char in magazine:record[ord(char) - ord('a')] += 1for char in ransomNote:record[ord(char) - ord('a')] -= 1return all([value >= 0 for value in record])
1.8 三数之和(哈希法梦碎的地方)
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
该题使用哈希法的话,去重的处理会非常复杂,所以使用双指针法比较方便,虽然相对简单了,但是还是涉及到一些去重的细节需要考虑清楚。
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:nums.sort() # 首先对nums进行排序result: List = []for index in range(len(nums)):if nums[index] > 0: # 如果排序后的首元大于0,则说明不存在这样的组合return resultif index > 0 and nums[index] == nums[index - 1]: # 对第一个元素进行去重continueleft: int = index + 1right: int = len(nums) - 1while left < right:if nums[index] + nums[left] + nums[right] > 0:right -= 1elif nums[index] + nums[left] + nums[right] < 0:left += 1else:result.append([nums[index], nums[left], nums[right]])while left < right and nums[left] == nums[left + 1]: # 对剩余两个元素进行去重left += 1while left < right and nums[right] == nums[right - 1]:right -= 1left += 1right -= 1return result
1.9 四数之和
18. 四数之和
给你一个由 n
个整数组成的数组 nums
,和一个目标值 target
。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]]
(若两个四元组元素一一对应,则认为两个四元组重复):
class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:nums.sort() # 排序result: List = []for i in range(len(nums)):if nums[i] > target and nums[i] > 0 and target > 0: # 剪枝breakif i > 0 and nums[i] == nums[i-1]: # 去重continuefor j in range(i+1, len(nums)):if nums[i] + nums[j] > target and target > 0: # 剪枝breakif j > i+1 and nums[j] == nums[j-1]: # 去重continue left: int = j + 1right: int = len(nums) - 1while left < right:s: int = nums[i] + nums[j] + nums[left] + nums[right]if s < target:left += 1elif s > target:right -= 1else:result.append([nums[i], nums[j], nums[left], nums[right]])while left < right and nums[left] == nums[left+1]:left += 1while left < right and nums[right] == nums[right-1]:right -= 1left += 1right -= 1return result
Reference
[1] Hello 算法
[2] 代码随想录
相关文章:

LeetCode刷题小记 三、【哈希表】
1. 哈希表 文章目录 1. 哈希表写在前面1.1 理论基础1.2 有效的字母异位词1.3 两个数组的交集1.4 快乐数1.5 两数之和1.6 四数相加||1.7 赎金信1.8 三数之和(哈希法梦碎的地方)1.9 四数之和 Reference 写在前面 本系列笔记主要作为笔者刷题的题解&#x…...

Zookeeper选举Leader源码剖析
Zookeeper选举Leader源码剖析 leader选举流程 参数说明 myid: 节点的唯一标识,手动设置zxid: 当前节点中最大(新)的事务idepoch-logic-clock: 同一轮投票过程中的逻辑时钟值相同,每投完一次值会增加 leader选举流程 默认投票给自己,优先选择…...

Redis(十六)缓存预热+缓存雪崩+缓存击穿+缓存穿透
文章目录 面试题缓存预热缓存雪崩解决方案 缓存穿透解决方案 缓存击穿解决方案案例:高并发聚划算业务 总结表格 面试题 缓存预热、雪崩、穿透、击穿分别是什么?你遇到过那几个情况?缓存预热你是怎么做的?如何避免或者减少缓存雪崩?穿透和击穿有什么区别?他两是…...

[已解决]npm淘宝镜像最新官方指引(2023.08.31)
最新的配置淘宝镜像的淘宝官方提供的方法 npm config set registry https://registry.npmmirror.com原来的 registry.npm.taobao.org 已替换为 registry.npmmirror.com ,当点击 registry.npm.taobao.org 会默认跳转到 registry.npmmirror.com 如果你想将npm的下载…...

ffmpeg之avformat_alloc_output_context2
函数原型: int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat,const char *format_name, const char *filename); 功能: 根据format_name或者filename或者oformat查找输出类型,并且初始化ctx结构。 参数: ctx:AVFormatContext…...

GitLab代码库提交量统计工具
1.说明 统计公司所有项目的提交情况,可指定分支和时间段,返回每个人的提交新增数、删除数和总数。 2.API 文档地址:http://公司gitlab域名/help/api/README.md 项目列表查询 返回示例: [{"id": 1, //项目ID"http…...

Python爬虫技术详解:从基础到高级应用,实战与应对反爬虫策略【第93篇—Python爬虫】
前言 随着互联网的快速发展,网络上的信息爆炸式增长,而爬虫技术成为了获取和处理大量数据的重要手段之一。在Python中,requests模块是一个强大而灵活的工具,用于发送HTTP请求,获取网页内容。本文将介绍requests模块的…...

关于TypeReference的使用
关于TypeReference的使用 在项目中,有遇到TypeReference的使用,其主要在字符串转对象过程中,对于序列化和反序列化中也有效果,将字符串转换成自定义对象. 1 说明 以常见为例,在com.alibaba.fastjson包下面的TypeReference类,是指Type的Reference,表示某类型的一个指…...

阿里大文娱前端一面
引言 我目前本科大四,正在春招找前端,有大厂内推的友友可以聊一聊,球球给孩子的机会吧。 我整理了一份10w字的前端技术文档:https://qx8wba2yxsl.feishu.cn/docx/Vb5Zdq7CGoPAsZxMLztc53E1n0k?fromfrom_copylink,对…...

Clickhouse系列之连接工具连接、数据类型和数据库
基本操作 一、使用连接工具连接二、数据类型1、数字类型IntFloatDecimal 2、字符串类型StringFixedStringUUID 3、时间类型DateTimeDateTime64Date 4、复合类型ArrayEnum 5、特殊类型Nullable 三、数据库 一、使用连接工具连接 上一篇介绍了clickhouse的命令行登录,…...

【深入理解设计模式】原型设计模式
原型设计模式 原型设计模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制已有对象来创建新对象,而无需直接依赖它们的具体类。这种模式通常用于需要频繁创建相似对象的场景,以避免昂贵的创建操作或初始化过…...

Python算法题集_图论(课程表)
Python算法题集_课程表 题207:课程表1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【循环递归全算】2) 改进版一【循环递归缓存】3) 改进版二【循环递归缓存反向计算】4) 改进版三【迭代剥离计数器检测】 4. 最优算法5. 相关资源 本…...

视频评论挖掘软件|抖音视频下载工具
针对抖音视频下载的需求,我们开发了一款功能强大的工具,旨在解决用户在获取抖音视频时需要逐个复制链接、下载的繁琐问题。我们希望用户能够通过简单的关键词搜索,实现自动批量抓取视频,并根据需要进行选择性批量下载。因此&#…...

Linux学习方法-框架学习法——Linux驱动架构的演进
配套视频学习链接:https://www.bilibili.com/video/BV1HE411w7by?p4&vd_sourced488bc722b90657aaa06a1e8647eddfc 目录 Linux驱动演进的过程 Linux驱动的原始架构(Linux V2.4) 平台总线架构(platform) Linux设备树 Linux驱动演进的趋势 Linux驱动演进的过程…...

Spring Boot基础面试问题(一)
上篇文章中10个Spring Boot面试问题的标准答案: 什么是Spring Boot?它与Spring框架有什么区别? 标准回答:Spring Boot是基于Spring框架的快速开发框架,它简化了Spring应用程序的搭建和配置过程,提供了一套自…...

电路设计(28)——交通灯控制器的multisim仿真
1.功能设定 南北、东西两道的红灯时间、绿灯时间均为24S,数码管显示倒计时。在绿灯的最后5S内,黄灯闪烁。有夜间模式:按下按键进入夜间模式。在夜间模式下,数码管显示计数最大值,两个方向的黄灯不停闪烁。 2.电路设计 …...

【Docker】免费使用的腾讯云容器镜像服务
需要云服务器等云产品来学习Linux可以移步/-->腾讯云<--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。 目录 1、设置密码 2、登录实例(sudo docker login xxxxxx) 3、新建命名空间(每个命名空…...

如何让qml使用opengl es
要让 QML 使用 OpenGL ES,您需要确保项目配置正确,并在应用程序中使用 QSurfaceFormat 来设置 OpenGL ES 渲染。 以下是一些步骤来配置 QML 使用 OpenGL ES: 1、项目配置:在您的项目配置文件(例如 .pro 文件…...

金航标电子位于广西柳州鹿寨县天线生产基地于大年正月初九开工了!!
金航标电子位于广西柳州鹿寨县天线生产基地于大年正月初九开工了!!!金航标kinghelm( http://www.kinghelm.com.cn )总部位于中国深圳市,兼顾技术、成本、管理、效率和可持续发展。东莞塘厦实验室全电波暗…...

FlinkCDC详解
1、FlinkCDC是什么 1.1 CDC是什么 CDC是Chanage Data Capture(数据变更捕获)的简称。其核心原理就是监测并捕获数据库的变动(例如增删改),将这些变更按照发生顺序捕获,将捕获到的数据,写入数据…...

力扣代码学习日记六
Problem: 66. 加一 思路 给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外,这个整数不会以零开头。 示例 1: 输…...

「Python系列」Python标准库
文章目录 一、 os 模块:文件和目录操作二、 sys 模块:与Python解释器交互三、 datetime 模块:日期和时间处理四、 json 模块:处理JSON数据五、 re 模块:正则表达式六、 time模块1. 获取当前时间2. 延迟执行(…...

虚拟列表【vue】等高虚拟列表/非等高虚拟列表
文章目录 1、等高虚拟列表2、非等高虚拟列表 1、等高虚拟列表 参考文章1 参考文章2 <!-- eslint-disable vue/multi-word-component-names --> <template><divclass"waterfall-wrapper"ref"waterfallWrapperRef"scroll"handleScro…...

【MySQL】如何理解索引(高频面试点)
一、前言 首先这个博客会介绍一些关于MySQL中索引的基本内容以及一些基本的语法,当然里面也会有些常见的面试题的解答。 二、关于索引 1、概念 索引是一种能够帮助MySQL高效的去磁盘检索数据的一种数据结构。在MySQL的Innodb存储引擎中呢,采用的是B树的…...

NXP实战笔记(四):S32K3xx如何产生中心对称三相六路波形
目录 1、概述 1.1、理论基础 2、RTD实现 2.1、Emios时基配置 2.1.1、EmiosMcl 2.1.2、EmiosCommon 2.2、Emios PWM配置 2.3、TRGMUX 2.4、LCU 2.5、外设信号配置 3、代码实现 4、测试结果 1、概述 电机控制中需要产生三相六路SVPWM进行占空比与周期调制,怎么通过RT…...

关于uniapp H5应用无法在触摸屏正常显示的处理办法
关于uniapp H5应用无法在触摸屏正常显示的处理办法 1、问题2、处理3、建议 1、问题 前几天, 客户反馈在安卓触摸大屏上无法正确打开web系统(uni-app vue3开发的h5 应用),有些页面显示不出内容。该应用在 pc 端和手机端都可以正常…...

Stable Diffusion 3 发布,AI生图效果,再次到达全新里程碑!
AI生图效果,再次到达全新里程碑! Prompt:Epic anime artwork of a wizard atop a mountain at night casting a cosmic spell into the dark sky that says "Stable Diffusion 3" made out of colorful energy 提示(意译…...

单例模式怎样实现单例(独例)?
在类定义中加入私有属性 __init__flag Ture,在随后的初始化处理中,判断该属性为真时进行相应的初始化操作,否则,跳过相应的初始化操作。这个机制,保证在进行后续的调用时,不再占用额外的内存开销。 当然了,…...

MySQL——基础内容
目录 第01章_数据库概述 关系型数据库(RDBMS)——表、关系模型 非关系型数据库(非RDBMS) 表、记录、字段 表的关联关系 一对一关联 一对多关系 多对多 自我引用 第02章_MySQL环境搭建 登录命令 常用命令 show databases; create database use 数据库名 show tables 第03章…...

node 之 初步认识
思考:为什么JavaScript可以在浏览器中被执行 代执行的js代码——JavaScript解析引擎 不同的浏览器使用不同的JavaScript解析引擎 Chrome 浏览器 》 V8 Firefox浏览器 》OdinMonkey(奥丁猴) Safri浏览器 》JSCore IE浏览器 》Chakra(查克拉) e…...