Python - 深夜数据结构与算法之 Map Set

news2024/9/21 20:33:29

目录

一.引言

二.Map 与 Set

1.Hash Table

2.Hash Function

3.Hash Collisions

4.Java/Python Code

三.经典算法实战

1.Two-Sum [1]

2.Group-Anagrams [49]

3.Valid-Anagram [242]

四.总结


一.引言

前面介绍了列表 List 及其衍生的栈 Stack 与队列 Queue,接下来我们介绍常见的数据结构 Map 与 Set,这两个数据结构底层结构很多都是通过 Hash Table 实现,当然也有使用二叉树的案例。下面我们简单学习下 Hash Table 及其相关的 Map & Set。

二.Map 与 Set

1.Hash Table

通过 Hash 函数我们可以将我们需要存储的值映射到一个下标 index 并存储到数组中。因为其是一一对应的关系,所以天然的也可以实现去重。

2.Hash Function

下面是 Hash Function 映射的示例,这里我们存储的 key 是一个 String,存储的 Value 是 Int,我们通过获取每个字符 Char 的 ASCII 码并相加 mod 10,最终得到 9,从而将 value=20 存储在数组中 9 的位置。

3.Hash Collisions

Hash 碰撞,对于一个 Hash Table 而言,好的 Hash Function 可以使得到的元素存储索引尽可能的分散,但实际情况中难免出现不同字符 Hash 到相同为止的情况。当使用 ASCII + mod 的 Hash Function 时,就会出现碰撞的情况,此时一种做法是直接覆盖,这样做会造成数据的丢失或异常,还有一种做法就是做一条 '拉链',我们在索引 9 处构造一个链表,每当碰撞时都会给链表添加一个新的 Node,以此类推。使用 Hash Table 寻找索引的时间复杂度为 o(1),但是如果索引处出现多次重复将会导致查询的复杂度升级为 o(n),所以对于 Hash Table 而言,一个好的 Hash Function 很关键。

4.Java/Python Code

◆ Java

由 Hash Table 衍生而来最常用的数据结构就是 Map 与 Set,其中 Map 的 key 不重复,value 可以重复,其存储 k-v 对;而 Set 则是只存储不重复的元素。 最常用的就是 HashMap、HashSet,可以在 Collections 库中找到实现。

◆ Python

Python 使用 dict{} 与 set{} 实现,相比 Java 会更加简洁一点,但其存储特性和功能是一致的。 

三.经典算法实战

1.Two-Sum [1]

两数之和: https://leetcode-cn.com/problems/two-sum/

◆ 题目分析

算法的经典老大哥,在数组遍历的同时,我们引入 HashMap 记录遍历的值与索引,空间换时间提高算法效率。

◆ 索引缓存

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        re = {}

        for i in range(len(nums)):
            cur_val = target - nums[i]
            # 寻找与 target 的差值是否在 re 中
            if cur_val in re:
                # 在的话直接返回索引
                return [i, re[cur_val]]
            else:
                re[nums[i]] = i

通过 HashMap 存储对应元素的值与索引,如果找到匹配的值,返回二者的下标,没有找到匹配则存储继续向后遍历。 

2.Group-Anagrams [49]

字母异位词分组: https://leetcode.cn/problems/group-anagrams/

◆ 题目分析

字母异位词是指两个字符串字符与数量相同,但是位置不同的字符,例如 "abc"、"bca"、"cba" 等等。这里一个简单的方法就是对字符串进行排序即 sort,排序后的字符串有序,这样我们根据 key 构造 HashMap 存储即可。

◆ 字符排序

class Solution(object):

    def groupAnagrams(self, strs):
        """
        :type strs: List[str]
        :rtype: List[List[str]]
        """
        re = {}

        for text in strs:
            # 排序后的字符作为 key
            sorted_text = ''.join(sorted(text))
            if sorted_text not in re:
                re[sorted_text] = []
            # 添加结果
            re[sorted_text].append(text)
        
        return re.values()

这个题目和后面第 242 题的有效的字母异位词比较类似,都是借助 HashTable 实现去重和比较。 

3.Valid-Anagram [242]

有效的字母异位词: https://leetcode.cn/problems/valid-anagram

◆ 题目分析

有效的字母异位词,这里 Anagram 就是英文里异位词的意思,给定两个字符串,如果二者的每个字符出现次数一样,则认为二者互为异位词。因为是针对每个字符 Char 其出现次数一样,这里我们可以很快想到使用 WordCount,而最简单的办法就是构造 HashMap。

◆ WordCount

class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        # 长度不一致直接返回
        if len(s) != len(t):
            return False

        # 统计字符数量是否相等
        word_count = {}
        
        # 遍历 s 的 char
        for char in s:
            if char not in word_count:
                word_count[char] = [0, 0]
            word_count[char][0] += 1
        
        # 遍历 t 的 char
        for char in t:
            # 情况1: 不满足包含相同字符
            if char not in word_count:
                return False
            word_count[char][1] += 1

        for listValue in word_count.values():
            # 情况2: 不满足字符数量相同
            if listValue[0] != listValue[1]:
                return False
        
        return True
            

使用 dict 记录 key 是否相同,key 不同直接返回 False;key 相同的情况下判断数组中 s、t 的 char 数量是否相同即可。 

◆ WordCount Plus

class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if len(s) != len(t):
            return False

        # 统计字符数量是否相等
        word_count = {}
        for i in range(len(s)):

            # 加减抵消
            if t[i] not in word_count:
                word_count[t[i]] = 0
            if s[i] not in word_count:
                word_count[s[i]] = 0

            word_count[s[i]] += 1
            word_count[t[i]] -= 1

        for count in word_count.values():
            if count != 0:
                return False

        return True

上面这个方法使用 [0, 0] 的计数数组进行 Char 的比较,还有一个省事的办法是使用一个变量,s 使用 +,t 使用 - ,如果遍历完该变量为 0,则代表 Char 数量一致。内存

◆ WordCount Pro Max

class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if len(s) != len(t):
            return False

        # 统计字符数量是否相等
        word_count = [0] * 26

        for char in s:
            word_count[ord(char) - ord('a')] += 1

        for char in t:
            word_count[ord(char) - ord('a')] -= 1

        # 判断 0
        for count in word_count:
            if count != 0:
                return False

        return True

这里使用 ASCII 码 + List 实现了上面简介里最朴素的 Hash Function,这里使用 ord 获取 ASCII 码,使用 - ord('a') 获取相对位置,虽然用了 [0] x 26 限制了空间,但是空间复杂度还是不好。这里主要是引入 ord ASCII 码的思想,而上面的 Plus 则是引入抵消的思想。

四.总结

这里 HashMap 和 Set 的题目相比 ArrayList、Stack 和 Queue 要少一些,但是其核心思想需要掌握,那就是去重以及其空间换时间的操作。除此之外,这里我们学到了字符串的排序与字符串的 ASCII 码,这些辅助办法在后续的题目中也会需要。Keep Fighting!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1325353.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SMART PLC MODBUS-RTU通信(多台同一设备通信优化写法)

MODBUS通信基础介绍请查看下面文章链接: https://rxxw-control.blog.csdn.net/article/details/133755924https://rxxw-control.blog.csdn.net/article/details/133755924多台同一设备的MODBUS-RTU通信,我们在编写轮询程序的时候,可以采用站号变址的方式实现。 1、轮询状态…

【漏洞复现】CVE-2023-6895 IP网络对讲广播系统远程命令执行

漏洞描述 杭州海康威视数字技术有限公司IP网络对讲广播系统。 海康威视对讲广播系统3.0.3_20201113_RELEASE(HIK)存在漏洞。它已被宣布为关键。该漏洞影响文件/php/ping.php 的未知代码。使用输入 netstat -ano 操作参数 jsondata[ip] 会导致 os 命令注入。 开发语言:PHP 开…

Java算法(十):【数据结构与算法】之 冒泡排序 详细流程图和源代码实现

冒泡排序 public static void main(String[] LiuJinTao) {// 1、冒泡排序int [] arr {22, 44, 33, 55, 11};for (int i 0; i < arr.length -1; i) {for (int j 0; j < arr.length - 1 - i; j) {if (arr[j] > arr[j 1]) {int temp arr[j];arr[j] arr[j 1];arr[j…

数字图像处理 基于Numpy、PyTorch在频率空间中建模运动模糊

一、简述 运动模糊在图像中很常见,它会降低图像的价值,因为它会破坏图像中包含的数据。在计算机视觉中,通常通过使用许多不同的模糊增强来训练神经网络以适应这种模糊。建模模糊或图像退化的概念来自图像恢复,这是逆转退化影响的过程,以便人类或算法可以辨别原始捕获的数据…

【技术前沿】数字孪生技术助推城市智慧供热:探讨换热站3D可视化的创新之路

换热站作为供热系统不可或缺的一部分&#xff0c;其能源消耗对城市环保至关重要。在双碳目标下&#xff0c;供热企业可通过搭建智慧供热系统&#xff0c;实现供热方式的低碳、高效、智能化&#xff0c;从而减少碳排放和能源浪费。 通过应用物联网、大数据等高新技术&#xff0…

whisper深入-语者分离

文章目录 学习目标&#xff1a;如何使用whisper学习内容一&#xff1a;whisper 转文字1.1 使用whisper.load_model()方法下载&#xff0c;加载1.2 使用实例对文件进行转录1.3 实战 学习内容二&#xff1a;语者分离&#xff08;pyannote.audio&#xff09;pyannote.audio是huggi…

常用的 JSON XML INI CSV 数据格式详解

目录 0 引言1 JSON1.1 数据格式1.2 应用场景 2 XML2.1 数据格式2.2 应用场景 3 INI3.1 数据格式3.2 应用场景 4 CSV4.1 数据格式4.2 应用场景 5 总结 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;C专栏&#x1f4a5; 标题&#xff1a;常用的 XM…

【数据结构和算法】 K 和数对的最大数目

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;双指针排序 三、代码 3.1 方法一&#xff1a;双指针排序 3.2 方法二&#xff1…

制造行业定制软件解决方案——工业信息采集平台

摘要&#xff1a;针对目前企业在线检测数据信号种类繁多&#xff0c;缺乏统一监控人员和及时处置措施等问题。蓝鹏测控开发针对企业工业生产的在线数据的集中采集分析平台&#xff0c;通过该工业信息采集平台可将企业日常各种仪表设备能够得到数据进行集中分析处理存储&#xf…

mysql部署 --(docker)

先查找MySQL 镜像 Docker search mysql &#xff1b; 拉取mysql镜像&#xff0c;默认拉取最新的&#xff1b; 创建mysql容器&#xff0c;-p 代表端口映射&#xff0c;格式为 宿主机端口&#xff1a;容器运行端口 -e 代表添加环境变量&#xff0c;MYSQL_ROOT_PASSWORD是root用户…

【K8s】#1使用kuboard-spray安装K8s集群

文章目录 搭建k8s集群1.推荐配置1.1.服务器配置1.2.软件版本 2.使用Kuboard-Spray安装k8s集群2.1.配置要求2.2.操作系统兼容性2.3.安装 Kuboard-Spray2.4.加载离线资源包2.5.规划并安装集群2.6.安装成功2.7.访问集群 3.涉及的命令3.1.linux 4.问题汇总Q1&#xff1a;启动离线集…

一个正则快速找到在ES中使用profile的时产生慢查询的分片

在es中使用profile分析慢查询的时候&#xff0c;往往因为分片过多&#xff0c;或者因为查询条件太复杂&#xff0c;分析的结果几十万行。在kibana上点半天&#xff0c;也找不到一个耗时长的分片。 kibana上可以通过正则来匹配。其实我们只需要匹配到耗时大于10秒的请求。 检索语…

HackTheBox - Medium - Windows - Aero

Aero 这个机器利用了今年比较新的cve&#xff0c;关于windows11的漏洞&#xff0c;类似于lnk、scf&#xff0c;但这个危害更高&#xff0c;通过易受攻击的windows11 利用theme、msstyles来实现RCE. Aero 是一台中等难度的 Windows 机器&#xff0c;最近有两个 CVE&#xff1a;…

argmin与argmax

argmin 是一个数学术语&#xff0c;用于表示一个函数在其定义域中取得最小值的参数值&#xff08;自变量的值&#xff09;&#xff0c;而不是最小值本身。 具体来说&#xff0c;argmin 表示函数的自变量&#xff08;通常是一个实数或向量&#xff09;&#xff0c;当输入到该函数…

文件传输软件SecureFX mac支持多种协议

SecureFX mac是一款文件传输客户端&#xff0c;可在 Mac 操作系统上使用。它由 VanDyke Software 公司开发&#xff0c;旨在为用户提供安全、可靠、高效的文件传输服务。 SecureFX 支持多种协议&#xff0c;包括 SFTP、SCP、FTP、FTP over SSL/TLS 和 HTTP/S。它使用强大的加密…

java并发-ConcurrentHashMap 在Java7 和 8 的区别

文章目录 1.Java 7 版本的 ConcurrentHashMap2.Java 8 版本的 ConcurrentHashMap3.分析 Java 8 版本的 ConcurrentHashMap 的重要源码3.1.Node 节点3.2.put 方法源码分析3.3.get 方法源码分析 4.对比 Java7 和 Java8 的异同和优缺点4.1.并发度4.2.保证并发安全的原理4.3.遇到 H…

Spring Boot构建项目常用注解

忙着去耍帅&#xff0c;后期补充完整.....................................

文件上传 [SWPUCTF 2021 新生赛]easyupload1.0

打开题目 上传文件格式为jpg类型的一句话木马上去 木马内容为 bp抓包把文件后缀改为php 可以看到上传成功且给了我们上传路径&#xff0c;访问一下 访问成功 我们用蚁剑连接一下&#xff0c;但是找到的是假的flag 那我们用hackbar&#xff08;也可以用bp&#xff09; 执行命…

法线贴图实现衣服上皱褶特效

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 法线贴图在3D建模中扮演着重要的角色&#xff0c;它通过模拟表面的微…