代码随想录算法训练营第6天 | 242.有效的字母异位词 + 349. 两个数组的交集 + 202. 快乐数 + 1. 两数之和

目录

今日任务:

哈希表理论基础

哈希表理论:

常见的三种哈希结构:

242.有效的字母异位词

数组

 default

Counter 

349.两个数据集的交集

202.快乐数

集合法:

暴力法:

1.两数之和

字典:

暴力法: 


今日任务:

  • 哈希表理论基础
  • 242.有效的字母异位词
  • 349.两个数组的交集
  • 202.快乐数
  • 1.两数之和

哈希表理论基础

哈希表理论:

哈希表(散列表,Hash table):

  • 直白来讲,其实数组就是一张哈希表
  • 通过拿空间换时间
  • 哈希表中关键码就是数组下标,通过下标直接访问数组的元素
  • 一般哈希表都是用来判断一个元素是否出现在集合中

例如:查询一个名字是否在这个学校

复杂度:如果使用枚举法为O(n),哈希表为O(1)

思路:将这所学校里学生的名字都存在哈希表中,查询时通过索引直接就可以知道这个名字是否在这个学校中,将学生名字映射到哈希表上就涉及到了hash function

哈希函数(hash function):

  • hash function通过hashCode把名字转化为数值,一般hashCode是通过特定编码的方式,可以将其他数据格式转化为不同的数值,这样就可以把学生名字映射为哈希表上的索引数字了

哈希碰撞:

  • 小王与小李都映射到索引下标为1的位置上,这一现象称为哈希碰撞
  • 解决方式:拉链法、线性探测法

拉链法:

刚刚小李和小王在索引1的位置发生了冲突,发生冲突的元素都被存储在链表中。 这样我们就可以通过索引找到小李和小王了

 其实拉链法就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也  不会因为链表太长而在查找上浪费太多时间。

线性探测法:

  • 使用线性探测法,一定要保证tableSize大于dataSize。 我们需要依靠哈希表中的空位来解决碰撞问题。

例如冲突的位置,放了小李,那么就向下找一个空位放置小王的信息。所以要求tableSize一定要大于dataSize ,要不然哈希表上就没有空置的位置来存放 冲突的数据了。如图所示:

常见的三种哈希结构:

  • 数组
  • set
  • map(映射)

242.有效的字母异位词

题目链接:242. 有效的字母异位词 - 力扣(LeetCode)

分析:

  • 用长度为26的数组,分别对应26个字母
  • 循环s,在相应的下标上加1
  • 循环t,在相应的下标上减1
  • 最后循环record的数组检查是否都为0

数组

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        record = [0] * 26

        for i in s:
            record[ord(i) - ord('a')] += 1
        
        for j in t:
            record[ord(j) - ord('a')] -= 1

        for k in range(26):
            if record[k] != 0:
                return False
        
        return True

 default

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        from collections import defaultdict

        s_dict = defaultdict(int)
        t_dict = defaultdict(int)

        for x in s:
            s_dict[x] += 1

        for x in t:
            t_dict[x] += 1

        return s_dict == t_dict 

Counter 

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        from collections import Counter
        s_count = Counter(s)
        t_count = Counter(t)
        return s_count == t_count

如果不太清楚python的collections,请参考: Python——详解collections工具库 - 知乎 (zhihu.com)


349.两个数据集的交集

题目链接:349. 两个数组的交集 - 力扣(LeetCode)

分析:

  • 使用set进行去重处理
  • 之后循环其中一个list,看是否存在另一个list中,若存在,添加到最后的final 
class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        nums_set1 = set(nums1)
        nums_set2 = set(nums2)

        final = []

        for i in nums_set1:
            if i in nums_set2:
                final.append(i)

        return final


202.快乐数

题目链接:202. 快乐数 - 力扣(LeetCode)

分析: 题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!

集合法:

class Solution:
    def isHappy(self, n: int) -> bool:
        n_set = set()
        n_sum = n
        
        while n_sum != 1:
            if n_sum in n_set:
                return False
            else:
                n_set.add(n_sum)

            n_sum = sum(int(i) ** 2 for i in str(n_sum))

        return True

暴力法:

class Solution:
    def isHappy(self, n: int) -> bool:
        sum = n
        count = 1

        while sum != 1:

            n_str = str(sum)

            sum = 0

            for i in n_str:
                sum += int(i) ** 2

            count += 1

            if count > 9999:
                return False

        if sum == 1:
            return True


1.两数之和

题目链接:1. 两数之和 - 力扣(LeetCode) 

分析:

字典:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        record = {}

        for index, value in enumerate(nums):
            if target - value in record:
                return [record[target - value], index]

            record[value] = index

        return []

暴力法:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i in range(len(nums)):
            for j in range(i + 1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值