Leetcode刷题笔记6:哈希表1

导语

leetcode刷题笔记记录,本篇博客记录哈希表部分的题目,主要题目包括:

  • 242 有效的字母异位词
  • 349 两个数组的交集
  • 202 快乐数
  • 1 两数之和

知识点

哈希表

哈希表(Hash table,散列表)是根据查找元素的值而直接进行访问的数据结构。一般哈希表都是用来快速判断一个元素是否出现集合里。

一般在Leetcode题目中我们有三种应用哈希表的形式,分别是:

  • 数组,应用于数字范围不太大的情形;
  • 集合,应用于数字范围很大的情形;
  • map,应用于还有其他对应值需要保存的情形。

Leetcode 242 有效的字母异位词

题目描述

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。注意: 若 s 和 t **中每个字符出现的次数都相同,则称 s 和 t **互为字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"
输出: true

提示:

  • 1 <= s.length, t.length <= 5 * 104
  • s 和 t 仅包含小写字母

进阶: 如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

解法

这道题目直接使用数组或者字典map就可以解决,解法如下:

# 数组解法
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        if len(s) != len(t):
            return False
        s_l ,t_l = [0] *26, [0]*26
        for s_char in s:
            s_l[ord(s_char)-ord("a")] += 1
        for t_char in t:
            t_l[ord(t_char)-ord("a")] += 1
        
        for i in range(26):
            if s_l[i] != t_l[i]:
                return False
        return True


# map解法
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        ss, tt = dict(), dict()
        for char in s:
            ss[char] = ss.get(char, 0) + 1
        for char in t:
            tt[char] = tt.get(char, 0) + 1
        return ss == tt

Leetcode 349 两个数组的交集

题目描述

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]

提示:

  • 1 <= nums1.length, nums2.length <= 1000
  • 0 <= nums1[i], nums2[i] <= 1000

解法

这道题目可以直接使用集合来实现,非常简洁。

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        return list(set(nums1) & set(nums2))

Leetcode 202 快乐数

题目描述

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:

输入: n = 19
输出: true
解释: 12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:

输入: n = 2
输出: false

提示:

  • 1 <= n <= 2^31 - 1

解法

这道题目乍一看是一道数学问题,其实并不是!题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!

当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。

所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。

解题代码如下:

class Solution:
    def isHappy(self, n: int) -> bool:
        def get_sum(n):
            ans = 0
            while n:
                n, r = divmod(n, 10)
                ans += r ** 2
            return ans
        
        result_s = set()
        result = get_sum(n)
        while result not in result_s:
            if result == 1:
                return True
            result_s.add(result)
            result = get_sum(result)
        return False

Leetcode 1 两数之和

题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

提示:

  • 2 <= nums.length <= 104
  • -109 <= nums[i] <= 109
  • -109 <= target <= 109
  • 只会存在一个有效答案

进阶: 你可以想出一个时间复杂度小于 O(n2) 的算法吗?

解法

当需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。本题需要一个集合来存放遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过。因为本题不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,需要使用 key-value结构来存放,key来存元素,value来存下标,那么使用map正合适

那么为什么不使用数组和set呢?这里有几点考虑:

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

此时就要选择另一种数据结构:map ,map是一种key-value的存储结构,可以用key保存数值,用value在保存数值所在的下标。在Python中可以很方便的通过字典来实现。

完整代码如下:

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i, num in enumerate(nums):
            index = hashtable.get(target-num, -1)
            if  index != -1:
                return [i, index]
            else:
                hashtable[num] = i

        return [-1, -1]

易错点

divmod

在Python中,divmod()函数是一个内置函数,用于执行整数的除法和取余运算,并以元组的形式返回结果。divmod()函数接受两个参数,通常用于执行两个整数的除法操作。它将第一个参数除以第二个参数,并返回一个包含两个值的元组,第一个值是整数除法的商,第二个值是整数除法的余数。语法:

divmod(x, y)

参数说明:

  • x: 被除数(整数)
  • y: 除数(整数)

返回值: divmod()函数返回一个包含两个值的元组 (quotient, remainder) ,其中 quotient 是整数除法的商, remainder 是整数除法的余数。

示例:

result = divmod(10, 3)
print(result)  # 输出:(3, 1)

# 可以通过元组的解包来获取商和余数
quotient, remainder = divmod(15, 4)
print("Quotient:", quotient)     # 输出:Quotient: 3
print("Remainder:", remainder)   # 输出:Remainder: 3

在上面的示例中,divmod(10, 3)执行整数除法,商为3,余数为1,并返回一个元组(3, 1)divmod(15, 4)也执行整数除法,商为3,余数为3,通过元组的解包分别将商和余数赋值给了quotientremainder变量。

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值