代码随想录算法训练营0513| 哈希表理论基础、242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和

哈希表理论基础

哈希表不是数据类型,类似一种解题思想。而这种思想在Python中可以用数组、集合、字典(C++中的说法是map)来实现

感觉这部分代码随想录文字部分讲的不太清楚,在B站看了“动画讲编程”(看动画,5分钟学会最经典的数据结构哈希表,C语言手写实现,不要错过呀_哔哩哔哩_bilibili)辅助理解。

目前的理解:哈希表就是将元素内容,转化为哈希表的下标索引,而将索引变得有意义。因此这种适用数据范围不是很大的题型。

因此在计算元素出现的次数计数排序(先计算出每个元素出现的次数,再将单一元素进行排序,并考虑元素出现的次数)时非常好用。只需要查询某下标索引对应的元素是数字几,就可得知

将元素内容转化为哈希表的过程,可以通过一个映射关系来完成,这个数学映射关系也就是之前“爱学习的饲养员”提到的哈希算法/哈希函数。

卡哥提到的“当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法”暂时不太理解,需要进一步积累

哈希碰撞感觉只是理解概念,需要结合题目。

242.有效的字母异位词

自刷的记忆还在,关键在于如何把字母转换为数组的下标索引。数组实现哈希表

这里的思路是,a-z共26个字母ASCII码连续。‘a’的ASCII码作为0,则‘z’的为25.出现这就将数组的对应位置的值加1。比较两个字符串最后输出的数组表是否相等即可

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        def calnums(strs):
            hashtable = [0]*26
            for i in strs:
                index = ord(i)-ord('a')#ASCII码转下标索引-->哈希函数
                hashtable[index] += 1
            return hashtable
        hash_s = calnums(s)
        hash_t = calnums(t)

        return hash_s==hash_t

349. 两个数组的交集

这个碰到我最初的思路是直接用集合的逻辑运算解决。

除了这种方法,卡哥还用了哈希表的方法解决,主要是:

思想是,将遍历数组A,把A转换为哈希表table存储,然后遍历B,把B中出现在table中的元素,重新存储起来。可以用集合实现,也可以用栈来实现。

①用字典实现哈希表(通过哈希表简化数据存储量)

在实现这种方法时,主要困难在字典和集合的基本函数上,总结了好多次了,但是还是记不住……

用到了字典的get函数和del函数( 元素用的是[]而不是() ),熟悉一下语法

遍历数组A,把A转换为哈希表table存储,数字为key,出现次数为value。然后遍历B,如果B中的元素,是table中的键,则将这个元素加入输出结果加入集合/栈

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        hashtable = {}#定义一个空字典
        for num in nums1:
            # 将num转变为字典的key,出现次数转变为对应value
            hashtable[num] = hashtable.get(num,0)+1#get的语法:如果有key=num,则返回对应value,否则返回默认值0
        
        output = []#使用栈来存储交集数据
        for num in nums2:
            if num in hashtable:#num是字典hashtable中的key
                output.append(num)
                del hashtable[num]#不删除的话,nums2出现重复元素则会导致output中也重复append
            
        return output

②用数组实现哈希表

和242类似,主要是遍历两个哈希表中的每个元素,如果对应位置的俩元素乘积不为0,则要加入输出的变量中。不再做复现

202.快乐数

如果想到了这个思路就比较简单:把出现过的各位数之和sum_nums存储在一个集合或者数组里,只要新求得的sum_nums在这个集合/数组里出现过了,就证明出现了死循环,否则就一直重复求和过程。

因此关键在于,如何求得各位上的数字的平方和。

两种思路:

①每次除10,每次得到个位数r,将r^2相加知道除10后的十位≠0

②讲数字转str以将各个位上的数字分开(很巧妙)

因为对集合的各个函数不太熟练,因此只尝试用集合实现,数组的(栈实现)暂不尝试。

class Solution:
    def isHappy(self, n: int) -> bool:
        def get_sum(n) :
            sum_nums = 0
            while n:#一直循环到n=0,求n所有位上的数的平方和
                n,r = divmod(n,10)#每次除10,则依次得到每一位上的数字
                sum_nums += r**2
            return sum_nums

        sum_set = set()
        while 1:
            sum_nums = get_sum(n)
            if sum_nums==1:
                return sum_nums==1
            else:
                if sum_nums in sum_set:
                    return sum_nums==1
                else :
                    sum_set.add(sum_nums)
                    n = sum_nums 

1.两数之和

同样难的是思路。感觉哈希表的用途还是在:原本比如是一个数组,每次只能获取一个信息。但转换为哈希表后,不管是索引还是存储的值都是具有意义的,那么同时可以获取两个信息--->将下标索引变得有意义。

或者是通过哈希函数这种映射关系,将原来的数据简化为只存储我们想要的信息,方便快速查询。

这个题的思路是用字典实现哈希表,选择key=num,而num对应的index作为value的原因是字典的查询是通过key来查询的。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        record = {}#建立一个字典
        for i in range(len(nums)):
            another_num = target-nums[i]
            if another_num in record and record[another_num]!=i:#另一半数已经出现过,且索引不是目前这个索引
                return [i,record[another_num]]

            record[nums[i]] = i

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值