【刷题笔记day6】哈希表与哈希集合基础 | 有效字母异位词 | 两个数组的交集 | 快乐数

本文介绍了哈希表和哈希集合的基本知识,包括它们的创建过程、哈希碰撞的解决方法以及复杂度分析。讨论了Python中字典和集合的区别,并分享了解决LC242、LC349和LC202等编程问题的思路,这些题目涉及有效字母异位词、两个数组的交集和快乐数的判断,利用哈希表和集合可以高效地解决问题。

哈希表与哈希集合基本知识

哈希表

哈希表又叫作散列表,有键值对,常用于统计词频或其他mapping关系。

数组其实也属于一种哈希表。其索引就相当于key,该位置存储的值就是value。

创建过程:key→哈希函数→内存地址→key | value 对应的内存地址

哈希碰撞:两个不同的key通过同一个hash函数得到相同的内存地址。

解决:

  1. 拉链法(Seperate Chaining),又叫 Open Hashing:在冲突的元素用链表的方式指向下一个元素(较常用)
  2. 线性探测法(Linear Probing),又叫Open Addressing, Close Hashing:一定要保证tableSize大于dataSize。当遇到冲突时,向后寻找空位填入元素。

复杂度分析:

  • 哈希表没有访问这个概念
  • 搜索:对key搜索是否存在该key。O(1),如果出现哈希碰撞:O(k),k为碰撞元素的个数(拉链法)。
  • 插入:通过key插入value值,O(1)
  • 删除:通过key删除value,O(1)

空间复杂度非常高

哈希集合

特征:无序,不重复

作用:检查某元素是否存在;重复元素

链表集合和树集合很少用到。

过程:元素通过哈希函数转换为哈希值,在哈希表对应位置里查找有无元素。

	有:对比是否相等。相等:更新。不相等:哈希冲突。
	无:直接存
  • 访问:不适用
  • 搜索:无哈希冲突:O(1);有哈希冲突:O(k)
  • 插入:无哈希冲突:O(1);有哈希冲突:O(k)
  • 删除:无哈希冲突:O(1);有哈希冲突:O(k)

Python 中字典和集合的区别

参见@及时行樂_的详细整理。

LC242 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1: 输入: s = "anagram", t = "nagaram" 输出: true
示例 2: 输入: s = "rat", t = "car" 输出: false
说明: 你可以假设字符串只包含小写字母。

题目中限定小写字母很关键,暗示我们可以利用数组和ASCII码来轻松解决这道题。

  • 先遍历一次s,统计词频并记录到table
  • 然后遍历一次t,将对应元素的频率减一
  • 最后检查table中是否有不为0的元素,有则说明不是异位词。
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
    	# 初始化哈希表
        table = [0] * 26
        for c in s:
            table[ord(c) - ord("a")] += 1
            
        for d in t:
            table[ord(d) - ord("a")] -= 1
            
        for i in table:
            if i != 0:
                return False
        return True

LC349 两个数组的交集

给定两个数组,编写一个函数来计算它们的交集。

这题的思路非常简单明了,将两个数组分别用集合表示,然后计算交集即可。

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        return list(set(nums1) & set(nums2))

更多详细的Python 中的集合运算,请参见链接。

LC202 快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,
也可能是 无限循环 但始终变不到 1。如果 可以变为  1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。

示例:
	输入:19
	输出:true
	解释:
	1^2 + 9^2 = 82
	8^2 + 2^2 = 68
	6^2 + 8^2 = 100
	1^2 + 0^2 + 0^2 = 1

初见本题容易找不到关键信息:无限循环,一旦发现就能明白,题目中的操作是会造成重复结果的,这样就显而易见用集合来解决这道题。

要取一个整数n的个位数字,就n % 10,要取十位,就n // 10,要取百位,就n // 100或者重复n // 10两次,以此类推。

class Solution:
    def isHappy(self, n: int) -> bool:
        record = set()
        digits = []
        
        while n not in record:
            record.add(n)
            
            # 取出 n 的每一位数
            while n != 0:
                digits.append(n % 10)
                n //= 10
            
            # 计算快乐数    
            num = 0
            while len(digits) != 0:
                num += digits.pop() ** 2
                
            if num == 1:
                return True
            n = num
            
        return False
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值