代码随想录Day6:哈希表Part1

文章介绍了如何使用哈希数据结构(如字典、数组和集合)解决LeetCode中的四个问题:判断字符串是否为Anagram、找出两个数组的交集、检查数字是否为快乐数以及查找两数之和。作者强调在选择数据结构时要考虑问题特性和数据规模的限制。
摘要由CSDN通过智能技术生成

Leetcode 242: 有效的Anagram:

讲解前:

这道题还是非常简单的,对比两个字符串是不是anagram我们只需要看两个字符串中每个字母出现的次数是否相同就可以了,遍历字符串然后记录字母出现次数最好的办法就是用字典/map

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        # create two dict for both string
        dict_s = {}
        dict_t = {}

        # iterate through both string to store all their letters
        for char in s:
            dict_s[char] = dict_s.get(char, 0) + 1
        
        for char in t:
            dict_t[char] = dict_t.get(char, 0) + 1
        
        return dict_s == dict_t
讲解后:

看完了卡哥的解法之后又对哈希解法有了新的认知,其实数组,集合,和字典都可以是哈希的一种表现方式,在不同的需求下我们要会选择更适合的数据结构,例如这道题用字典就是大材小用了,因为字母的数量只有26个是有限的,所以我们完全可以用数组来记录,index对应字母,里面存放的数据对应count,然后对于s我们加每个字母出现,然后再对于t我们减去每个字母出现,最后如果是anagram的话,数组里的数据应该全部为0才对

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        if len(s) != len(t):
            return False

        # create the hash list
        alpha = 26 * [0]

        # iterate through s and t to count the appearance of each letter
        for i in range(len(s)):
            alpha[ord(s[i]) - ord('a')] += 1
            alpha[ord(t[i]) - ord('a')] -= 1
        
        # check if every element is 0
        for i in alpha:
            if i != 0:
                return False

        return True

Leetcode 349: 两个数组的交集

讲解前:

这道题首先我看到的一瞬间,一提到交集,那其实就是和集合有关,python的set中自己就直接有intersection的函数,我们要明白两个数组的交集是不可能有重复的元素的因为不重要,只要有一个相同的就可以,所以我想的就是直接把两个数组变成两个集合然后直接利用函数或者& operator解决问题,虽然不知道这种方法合不合理

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        # turn the two list into set
        set1 = set(nums1)
        set2 = set(nums2)

        # return their intersection
        return list(set1 & set2)
讲解后:

看了卡哥的讲解之后呢发现我上面这种写法确实也算小聪明,正常情况下我们可以只把一个数组变为集合然后去遍历另一个数组查看里面的数值是否在集合中出现过,如果出现过就加入到result 集合中去就可以了,卡哥讲的数组实现的过程大同小异,我就没有复刻

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        res = set()

        set1 = set(nums1)

        for num in nums2:
            if num in set1:
                res.add(num)
        
        return list(res)

Leetcode 202: 快乐数

讲解前:

我第一眼看到这个题的时候其实觉得很麻烦,每次一看到这种要把一个int 分成个位十位百位的时候就觉得很麻烦不想经历mod的process,但是我后面觉得其实可以直接把传入的number转成int然后遍历就很方便了,但是我又发现一个问题就是我们怎么发现如果不是快乐数然后一直在循环呢?然后我又仔细阅读了一遍题目然后重新想了一想,并且发现了代码随想录文章中题解一开始告诉的条件,就是我们要知道如果这个数字不是快乐数,那么其实每位数字上的平方求和是陷入一个循环,什么是循环,也就是说一定会有和重复出现,这样的话其实就可以变成一个查看一个数是否出现过的问题,也就是哈希表最擅长解决的问题

class Solution:
    def isHappy(self, n: int) -> bool:
        # create set to store sum and convert num to string and initialize sum0
        sum_set = set()
        num = str(n)
        sum0 = 0

        # keep checking if the current sum is 1 or it has be created more than once
        while True:
            for char in num:
                sum0 = sum0 + int(char) ** 2
            
            if sum0 == 1:
                return True
            elif sum0 not in sum_set:
                sum_set.add(sum0)
            else:
                return False
            
            num = str(sum0)
            sum0 = 0
讲解后:

代码随想录的文章里的思路就和上面我解释的一样,然后代码实现中,有非常多的版本,主要也是python语言的特殊性可以把代码精简再精简,我这里复制粘贴一份也用字符串的精简解法

class Solution:
   def isHappy(self, n: int) -> bool:
       seen = set()
       while n != 1:
           n = sum(int(i) ** 2 for i in str(n))
           if n in seen:
               return False
           seen.add(n)
       return True

Leetcode 1: 两数之和

讲解前:

这道题实在是太经典了,没什么好说的,做过无数次了,就是利用字典的哈希解法

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hash_map = {}
        for i, num in enumerate(nums):
            diff = target - num
            if diff not in hash_map.keys():
                hash_map[num] = i
            else:
                return [i, hash_map[diff]]

在我们遍历每一个数组中元素的时候我们都用target - num来找到这个数字所需要的值来得到target,如果需要的数字不在字典中,我们就暂时先把这个数字存进字典然后继续遍历,当我们找到了一个数字并且他需要的diff同时也在之前就存在字典里时,我们就成功找到了,返回这个数组和字典中diff的下标就可以了

讲解后:

卡哥的讲解非常清晰易懂,思路是一样的,我希望以后每道题都能理解第一,能不死记硬背就不背

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值