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

哈希表理论基础—Hash table

  1. 用途:哈希表主要是用来判断某个元素是否出现在集合中
  2. 结构:常见的有3中结构:数组【用于范围小的情况】、set【用于范围大的情况】、map【有明确的key和value】。
  3. 顺序:对顺序没有要求

242.有效的字母异位词

题目:

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

示例 1:

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

说明:在两个字符串中,字母出现次数完全一样:a:3次,n:1次,g:1次,r:1次,m:1次

输出: true

示例 2:

输入: s = "rat", t = "car"

输出: false

注意:s 和 t 仅包含小写字母 

思路:

1、利用Counter方法,可以得出字符串中每个字母出现的次数

2、哈希法

代码:

1、Counter方法

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        from collections import Counter
        a=Counter(s)
        b=Counter(t)
        if a==b:
            return True
        else:
            return False

2、哈希法

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        record = [0] * 26  # 因为字符串只由小写字母组成,创建一个record列表,记录字符出现的次数
        for i in s:  # 遍历s
            record[ord(i) - ord('a')] += 1  # 每个字母减去a的ASC值
        for i in t:  # 遍历t
            record[ord(i) - ord('a')] -= 1  # 这一步很重要,如果字母相同,在遍历s的基础上,在t中也出现时,减去出现的次数
        for i in range(26):
            if record[i] != 0:  # 最终看每个字母剩下的次数是不是为0,是的话,说明出现的字母是一样的
                return False
        return True  # 注意是和for对齐,这是循环结束的返回值
        

349. 两个数组的交集

题目:

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

示例 1:

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

输出:[2]

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]

输出:[9,4]

解释:[4,9] 也是可通过的

思路+代码:

1、先去重,再遍历,双指针,有相同的则返回相同的值。

自己写的:

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        result=[]   # 新建一个列表用于接收交集的数值
        nums1 = list(set(nums1))  # 利用集合先去重
        nums2 = list(set(nums2))
        for i in range(len(nums1)):
            for j in range(len(nums2)):
                if nums1[i]==nums2[j]:
                    result.append(nums1[i])
        return result

参考的:

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

 利用哈希表:集合

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        table = {}  # 创建一个哈希表,类型是字典
        for num in nums1:
            table[num] = table.get(num, 0) + 1  # 这句最难,0是一个默认值,用于num首次出现时返回

        result = set()  # 新建一个集合,用于返回交集的结果
        for num in nums2:
            if num in table:
                result.add(num)
                del table[num]  # 删除哈希中这个有交集的数字

        return list(result)

202. 快乐数

题目:

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

「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和

然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1

如果这个过程 结果为 1,那么这个数就是快乐数。

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

示例 1

输入:n = 19

输出:true

解释:

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

示例 2

输入:n = 2

输出:false

思路:

1、创建哈希表;

2、判断n是否在哈希表中,是否已经循环了;

3、把数字转为字符串,去除每个字符平方加和;

4、循环条件很重要:只要n不等于1 ,就循环。

代码:

class Solution:
    def isHappy(self, n: int) -> bool:
        seen = set()  # 创建一个哈希表,集合   创建数组也是可以的

        # 循环条件很重要,自己重写的时候忘了这一步
        while n != 1:  # 当给的这个数不是1的时候才能计算,是1的时候证明已经是快乐数了
            if n in seen:  # 如果当前这个数在哈希表中出现过,说明进入了循环,则不会在到1
                return False
            seen.add(n)  # 每次都把计算的数加入到集合中,便于后面判断是否进入循环

            # n = sum(int(digit) ** 2 for digit in str(n))  这行等于下面这段,是把数字加平方和的作用
            digit_square_sum = 0
            for digit in str(n):
                digit_square_sum += int(digit) ** 2
            n = digit_square_sum
            #  str(n)是将数字转为字符串;for digit in str(n)是去除数字中的每个字符

        return True

1. 两数之和——梦开始的地方!!

题目:

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

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

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

示例 1

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

示例 2

输入:nums = [3,2,4], target = 6

输出:[1,2]

示例 3

输入:nums = [3,3], target = 6

输出:[0,1]

提示:

只会存在一个有效答案

思路:

作为第一道题,做了好几遍了,还是不能顺畅做出来,说明总结的还是不够。

代码:

1、暴力法

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)):  # 这里是取i后面一位,很重要。
                if nums[i]+nums[j]==target:
                    return [i,j]

2、用字典

  • enumerate()函数很重要,它的作用是遍历数字,输出的是数组中数字的值和其对应的下标。
    class Solution:
        def twoSum(self, nums: List[int], target: int) -> List[int]:
            num_dict = {}  # 创建一个字典
            # 遍历数组
            for index, value in enumerate(nums):
                # target-value的值就是希望在数组中找到的数,如果能找到,说明True
                complement = target - value  
                
                if complement in num_dict:
                    return [num_dict[complement], index]
                num_dict[value] = index  
                # 这是不存的情况,要遍历下一个value了,把已经遍历过的数添加到新的列表中,
                # 便于后面遍历到别的数是,它作为complement存在【这很重要,是自己悟了好一会想通的!】
            return []

    总结:

  • 一共四道题目,分别用了数组,集合和字典映射的功能,对于哈希表的认知又加深了一步。
  • 希望下次遇到第一题,可以非常顺滑地写出字典这一套,就算是进步了。

你可能感兴趣的:(哈希表,散列表,数据结构)