【数据结构code】哈希表

242.有效的字母异位词

1、链接:

https://leetcode.cn/problems/valid-anagram/

2、思路

在这里插入图片描述
关注!!此处字符串只包含了26小写字母,因此可以使用数组来做哈希表
分析
需要保证每个字母出现的数量一样,即为有效—>true
因此需要判断某个字母是否在集合中---->哈希表
先创建数组,指定大小为26。
因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25。
储存第一个字符串中的每个字母出现的频次。在第二个数组中,减去每个字母出现的频次
那么最后检查一下,record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false

3、解答

class Solution(object):
    def isAnagram(self, s, t):
        """-》分析字母组成是否相同
        判断元素在不在集合中-》哈希表
        26个字母,范围有限-》哈希表选数组
        :type s: str
        :type t: str
        :rtype: bool
        """
        # 初始化哈希表 | 大小,初始值为0
        hashtable = [0] * 26
        # print(hashtable)
        # 第一个序列,出现则次数加1
        for i in range(len(s)):
            # ord()返回ascii码
            # 统计某个字母出现的频率
            hashtable[ord(s[i]) - ord('a')] += 1 # 减a是为了,自动获取下标。因为字母的ascii码是连续的
        for i in range(len(t)):
            hashtable[ord(t[i]) - ord('a')] -= 1
        for i in range(26):
            if hashtable[i] != 0:
                return False
        return True

4、注意

  • 此处26个字母,范围有限,可以使用数组作为哈希表
  • python中获取字母的ascii码:ord()

349.两个数组的交集

1、链接

https://leetcode.cn/problems/intersection-of-two-arrays/
在这里插入图片描述

2、思路

如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费!

采用集合

直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。

不要小瞧 这个耗时,在数据量大的情况,差距是很明显的。

3、解答

方法一:

直接返回两个set的交集

return list(set(nums1) & set(nums2))

方法二:
数组法,统计出现频率。若均大于0,则视为重合

class Solution(object):
    def intersection(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        # 法一数组法 | 统计出现频率,若均大于0,则重合
        count1 = [0]*1001
        count2 = [0]*1002
        result = [] # 存放结果
        for i in range(len(nums1)):
            count1[nums1[i]] += 1
        for j in range(len(nums2)):
            count2[nums2[j]] += 1
        for k in range(1001):
            if count1[k] * count2[k] > 0:
                result.append(k)
        return result

4、注意

关于python的集合

  • 集合:set 指的是无序的不重复的元素序列
  • 集合操作:交集、并集、差集
  • 创建集合
    在这里插入图片描述
  • 创建空的集合
    必须使用set( ) , 而不是{ } 。
    因为{ }是用来创建空字典的
  • 集合间的运算!
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # 集合a中包含而集合b中不包含的元素
{'r', 'd', 'b'}
>>> a | b                              # 集合a或b中包含的所有元素
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # 集合a和b中都包含了的元素
{'a', 'c'}
>>> a ^ b                              # 不同时包含于a和b的元素
{'r', 'd', 'b', 'm', 'z', 'l'}
  • 集合的基本操作
    添加元素:s.add( x )
    或 s.update( x ) # 这里的元素可以数列表,元组,字典等
    移除元素:s.remove( x )
    s.discard ( x )
    s.pop() # 随机删除集合中的一个元素

202.快乐数

1、链接

https://leetcode.cn/problems/happy-number/
在这里插入图片描述

2、思路

首先要拆解个位,十位进行求和。和sum会重复出现–>快速判断一个元素是否会在集合中出现!!!----> 哈希表
若重复出现 --> return false
若sum == 1 --> return true

3、解答

4、注意

python
创建空集合

set1 = ()

1.两数之和

1、链接

https://leetcode.cn/problems/two-sum/
在这里插入图片描述

2、思路

1、暴力法
很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。
2、哈希表
存储遍历过的下标
两数之和—> target - num 看得到的结果是否遍历过!

3、解答

seen = set()
for i,num in enumerate(nums):
      completment = target - num
      if completment in seen:
          return [nums.index(completment),i]
      seen.add(num)

4、注意

脑子要转过来!!!指定了两个数的和 —》 求差,看这个差值是否遍历过

454.四数相加Ⅱ

1、链接

https://leetcode.cn/problems/4sum-ii/
在这里插入图片描述
注意!!这里是四个数字来自于四个数组!!!

2、思路

先定义一个map,用于存放a+b的和,记录和即出现的频率
再遍历c和d, 看 -c-d是否存在于map中,若存在,则结果 += 出现的频率

3、解答

class Solution(object):
    def fourSumCount(self, nums1, nums2, nums3, nums4):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :type nums3: List[int]
        :type nums4: List[int]
        :rtype: int
        """
        # 使用字典
        hashmap = dict() # 初始化字典
        # 存放a+b的和
        for i in nums1:
            for j in nums2:
                if i + j in hashmap:
                    hashmap[i+j] += 1 # 若之前已经出现,则频率+1
                else:
                    hashmap[i+j] = 1 # 若第一次出现,频率为1
        count = 0
        for i in nums3:
            for j in nums4:
                temp = -i-j
                if temp in hashmap:
                    count += hashmap[temp] # 若存在,则count+频率
        return count

4、注意

求和的时候,要拆解为差!!
舍弃空间换时间 --》 工业开发也是这样

383.赎金信

1、链接

https://leetcode.cn/problems/ransom-note/
在这里插入图片描述

2、思路

哈希
哈希
数组!

3、解答

法三
        hashmap = [0]*26
        for i in ransomNote:
            hashmap[ord(i) - ord('a')] += 1
        for i in magazine:
            if hashmap[ord(i) - ord('a')] != 0:
                hashmap[ord(i) - ord('a')] -= 1
        if sum(hashmap) == 0:
            return True
        else:
            return False
        # 法一 使用数组
        ransom_count = [0]*26
        magazine_count = [0]*26
        for c in ransomNote:
            ransom_count[ord(c) - ord('a')] += 1
        for c in magazine:
            magazine_count[ord(c) - ord('a')] += 1
        # randsom字母频率要低于magzine字母频率
        return all(ransom_count[i] <= magazine_count[i] for i in range(26)) 

4、注意

all的使用

0.题目

1、链接

2、思路

3、解答

4、注意

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值