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

哈希表
常见的三种哈希结构:数组、set(集合)、map(映射)
要快速判断一个元素是否出现集合里,考虑哈希法!

242.有效的字母异位词

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

解题:

思路:将 a ~ z 的字符映射到数组 hush [0 ~ 25],对s和t字符串统计每个字符出现的频率,相减如果hush[0~26]都为0就表示出现频率相等。

  1. 如何将 a ~ z 映射到 0 ~ 25 ?通过ASCII码的相对值作为数组下标:ord[i]-ord['a']
  2. 如何判断是否s、t是否是字母异位词?通过相减:hush[0~25]均=0

注:1.不用分别统计频率,统计t的时候,直接在统计s求得的hush[]基础上相减;
2.python不能直接对字符进行运算,要用ord()求ASCII码值;
3.s是字符串,for i in s:i就是字符。

点击查看代码
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        hush=[0]*26
        for i in s:
            hush[ord(i)-ord('a')]+=1
        for i in t:
            hush[ord(i)-ord('a')]-=1
        for i in range(26):
            if hush[i]!=0:
                return False
        return True

349. 两个数组的交集

题目:给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
提示:0 <= nums1[i], nums2[i] <= 1000

解题:

经典思路:使用哈希表存储所有元素,再判断后存储结果。

  1. 哈希表的数据结构的选择?如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费!
    nums[i]值小于1000,可以用nums中的数值num作为下标。有限时:num可以作为数组下标;无限时:num可以作为集合的元素,也可以作为字典的键。
  2. 交集结果的数据结构的选择?集合:判断是否出现;数组:判断相乘是否为0。

一、都用集合,python写法太简洁了!

点击查看代码
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]:
        list1=[0]*1001
        list2=[0]*1001
        res=[]
        for i in range(len(nums1)):
            list1[nums1[i]]+=1
        for i in range(len(nums2)):
            list2[nums2[i]]+=1
        for i in range(1001):
            if list1[i]*list2[i]!=0:
                res.append(i)
        return res

三、用字典和集合,可以学习下python的字典用法
table.get(num, 0):如果 num 已经在 table 中,则返回其当前值(出现次数);如果 num 不在 table 中,则返回 0
将交集结果转换为列表并返回:list(res)

点击查看代码
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
        
        # 使用集合存储结果
        res = set()
        for num in nums2:
            if num in table:
                res.add(num)
                del table[num]
        
        return list(res)

202.快乐数

题目:编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

解题:

思路:无限循环表示不是快乐数,因此结果作为哈希表,出现过表示不是快乐数。
关键:如何取数值的每一位上的数,转换为字符串比较简单。

点击查看代码
class Solution:
    def isHappy(self, n: int) -> bool:
        res=set()
        while n not in res:
            res.add(n)
            new_num=self.get_sum(n)
            if new_num==1:
                return True
            else:
                n=new_num
        return False
    def get_sum(self,n:int):
        n_str=str(n)
        sum=0
        for char in n_str:
            sum+=int(char)**2
        return sum

1. 两数之和

题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

解题:
思路:遍历num同时找(target-num)有没有出现过,所以可以用哈希表。需要知道元素的下标,所以使用map的key value结构存放。
关键:1.遍历获取数组的value和index;2.因为要查询元素,返回下标:所以value作为key,index作为value。

一、map,字典

点击查看代码
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[index,record[target-value]]
            else:
                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]

心得:
哈希表关键在于如何选取数据结构,判断什么是下标
python语法:
集合增加元素:res.add()
数组增加元素:res.append()
字典增加元素:res[key]=value
查找一个元素是否在集合/列表:while n not in record
获取列表中的元素及对应索引:for index, value in enumerate(nums):

posted @ 2024-06-09 22:45  Y荷兰豆Y  阅读(2)  评论(0编辑  收藏  举报