代码随想录算法训练营day06 | 242.有效的字母异位词 、349. 两个数组的交集、202. 快乐数、1. 两数之和 (补卡)

哈希表part01(24.01.01)

安排:先独立做题,然后看视频讲解,然后看文章讲解,然后再重新做一遍题,把题目AC,最后整理成今日当天的博客。


学习时长:四小时
学习内容:自己尝试+pdf说明+视频+力扣题解+自己默写
学习感悟:需要看一下python版的数据结构课本了!


哈希表理论基础

1.什么时候想到用哈希法,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。  这句话很重要,大家在做哈希表题目都要思考这句话。

2.哈希表(英文名字为Hash table,国内也有一些算法书籍翻译为散列表,大家看到这两个名称知道都是指hash table就可以了)。

3.哈希表是根据关键码的值而直接进行访问的数据结构。(直白来讲其实数组就是一张哈希表。)

4.hash function ,也就是哈希函数。哈希函数如下图所示,通过hashCode把名字转化为数值,一般hashcode是通过特定编码方式,可以将其他数据格式转化为不同的数值,这样就把学生名字映射为哈希表上的索引数字了。

5.如果hashCode得到的数值大于哈希表的大小,也就是大于tableSize了,怎么办呢?(不再是单射),这种现象被称为哈希碰撞

一般哈希碰撞有两种解决方法, 拉链法和线性探测法。

  • 拉链法:发生冲突的元素都被存储在链表中。  

  

  • 线性探测法:

         一定要保证tableSize大于dataSize。(把冲突的多出来的数据放在哈希表的空位中。)

6.常见的三种哈希结构:数组(哈希表size比较小的时候,可以用二十六个字母来表示)、集合set(size比较大的时候)、映射map(k对应value的时候用map)

7.但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。

        


 242.有效的字母异位词

题目链接:力扣题目链接

笔记:

        1.我们可以统计s 各字符时执行 +1 ,统计 t 各字符时 −1 。

        2.代码中涉及到‘a’,是作为一个固定的参照物,依据各个字母的相对偏差来定位。ord()函数是一个内建函数,用于返回一个表示给定字符的 Unicode 字符的整数。

提交代码:

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        if len(s) != len(t):
            return False
        record = [0]*26
        for i in s:
            #并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
            record[ord(i)-ord('a')] += 1
        for i in t:
            record[ord(i)-ord('a')] -= 1
        for i in range(26):
            if record[i] != 0:
                return False
        return True

ord(i) 被用于获取字符串中每个字符的 Unicode 码点,然后通过减去 ord("a") 来得到相对于小写字母 'a' 的偏移量,以便在数组或列表中记录字母的频率。 


349. 两个数组的交集

题目链接:力扣题目链接

笔记:

        1.可以用数组做,也可以用set做。(set方法没懂,先跳了)

        2.集合添加元素用.add,数组添加元素用.append

提交代码:

class Solution: #用数组方法做
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        result = []
        count1 = [0]*1001
        count2 = [0]*1001
        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


202. 快乐数

题目链接:力扣题目链接

笔记:

       1. 题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。判断sum是否重复出现就可以使用unordered_set。

        2.某整数的各位数字求和,可以将整数转换为字符串,以便逐个访问数字:遍历每位字符并转成整数。

        

提交代码:

class Solution:
    def isHappy(self, n: int) -> bool:
        result = set()
        while n not in result:
            result.add(n)
            sum = 0
            n_str = str(n)
            for i in n_str:
                sum += int(i)**2
            if sum == 1:
                return True
            else:
                n = sum
        return False

1. 两数之和

题目链接:力扣题目链接

笔记:

        1.本题我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适

        2.使用数组和set来做哈希法的局限:数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。

        3.这道题我们需要给出一个元素(=target-此处的元素),判断这个元素是否出现过,如果出现过,返回这个元素的下标。

        4.enumerate() 是一个 Python 内置函数,它返回一个包含元素索引和元素值的迭代器。nums.index() 返回对应元素的索引

提交代码:前几天自己提交了暴力求解版本(两层循环嵌套)

class Solution: #暴力法
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        i=0
        l=len(nums)
        while i < l:
            for j in range(i+1,l):
                if nums[j] != target-nums[i]:
                    j += 1
                else:
                    return i,j
            i += 1           

 

class Solution: #哈希法
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        record = set()
        for i, num in enumerate(nums):
            complement = target - num
            if complement in record:
                return [nums.index(complement),i]
            else:
                record.add(num)

好像python的数据结构和c++的不一样,没有unordered_set, unordered_map这种东西,这节学的迷迷糊糊的...

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值