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

目录

242. 有效的字母异位词

349. 两个数组的交集

202. 快乐数

1. 两数之和


242. 有效的字母异位词

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

文章讲解:代码随想录

解题卡点:没想到使用数组和默认字典,使用了更麻烦的普通字典

        统计s的字母个数和出现次数,再使用t进行比较即可。

        可使用长度[0]*26的数组,数组也是简单的哈希表,遍历s字母出现一次+1,再遍历t字母出现一次-1,通过这种方式在一个数组上统计s和t的信息。如果是字母异位词,操作完后数组应为26个0。

        也可使用defaultdict,相较普通dict的好处是,在某个字母第一次出现时,可以直接写入字典,不用额外判断。

# 解法1:使用1个数组
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        st_list = [0]*26
        anagram_list = [0]*26
        for i in s:
            st_list[ord(i) - ord('a')] += 1
        for j in t:
            st_list[ord(j) - ord('a')] -= 1
        return st_list == anagram_list

# 解法2:使用2个默认字典
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        from collections import defaultdict
        s_dict = defaultdict(int)
        t_dict = defaultdict(int)
        for i in s:
            s_dict[i] += 1
        for j in t:
            t_dict[j] += 1
        return s_dict == t_dict

    # 时间复杂度 O(n+m) n和m为字符串s和t的长度
    # 空间复杂度 O(1) (将字符集大小视为常数,如ASCII字符集中,字符集大小为128)

349. 两个数组的交集

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

文章讲解:代码随想录

解题卡点:实现输出结果中元素唯一时,不清楚哪些内置函数是可以用的

        分别统计两个nums的数字个数与出现次数,进行比较得到交集。使用set可以大大简化去重操作,故下面写出了两个不使用set的方法。

        ①使用数组。使用数组做哈希题目的条件:限制了数值大小,哈希值跨度较小比较集中。本题中除了统计nums的循环外,还使用了遍历结果的第三个循环来实现去重操作。

        ②使用字典。在判断nums2元素在不在nums1中时,若在则将元素加入结果列表,同时删除nums1字典中的该元素,实现去重操作。

        Tips:

        哈希问题都用set可行么?不行,直接使用set不仅占用空间比数组大,而且速度要比数组慢。

# 解法1:只使用数组
class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        count1 = [0]*1001
        count2 = [0]*1001
        res = []
        for i in nums1:
            count1[i] += 1
        for j in nums2:
            count2[j] += 1
        for k in range(1001):
            if count1[k]*count2[k] > 0:
                res.append(k)
        return res

# 解法2:只使用字典
class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        from collections import defaultdict
        intersection_dict = defaultdict(int)
        res = []
        for i in nums1:
            intersection_dict[i] += 1
        for j in nums2:
            if j in intersection_dict:
                res.append(j)
                del(intersection_dict[j]) # 第一次出现并删除字典中该元素后,第二次遇见时就不会重复统计了
        return res

    # 时间复杂度 O(n+m) n和m为数组nums1和nums2的长度
    # 空间复杂度 O(n)

202. 快乐数

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

文章讲解:代码随想录

解题卡点:何时以及如何停止循环

        我的思路:递归计算各位上平方和,把本题的哈希考点误以为是制作数字平方表,没有理解解题的真正思路。

class Solution:
    def __init__(self):
        self.count = 1 # 控制递归次数
        self.num_square = {i: i**2 for i in range(10)} # 制作数字的平方表,后续直接查表

    def calculate(self, num): # 递归函数,计算数字各位上的平方和
        if self.count > 100: # 递归100次则退出递归
            return False
        if num == 1: # 各位上平方和为1则退出递归
            return True
        else:
            total = 0
            for i in str(num):
                total += self.num_square[int(i)]
            num = total
            self.count += 1
            return self.calculate(num)
    
    def isHappy(self, n: int) -> bool:
        return self.calculate(n)

        解答思路:记录每一次的各位上平方和,若和为1则是开心数,若和出现重复则该数进入无限循环得不到1,返回False。

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

    # 时间复杂度 O(logn)
    # 空间复杂度 O(logn)
    # 复杂度计算见 每日精华

1. 两数之和

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

文章讲解:代码随想录

解题卡点:想不到这题和哈希有什么关联

        什么时候使用哈希法:当需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。

        本题需要一个哈希表存放遍历过的元素,然后在遍历数组时查询是否存在某元素与当前元素相加等于target,若存在返回下标。需要知道元素对应的下标,故使用字典作为哈希。

         先判断该元素的之前元素有没有符合条件的,若没有再将当前元素添加到字典中。若顺序颠倒,遇上[3, 3] target=6会出问题。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        num_rec = dict()
        for idx, val in enumerate(nums):
            num_need = target - val
            if num_need in num_rec:
                return [idx, num_rec[num_need]]
            num_rec[val] = idx

    # 时间复杂度 O(n)
    # 空间复杂度 O(n)

        本题有四个重点需思考清楚:

        ①为什么想到使用哈希表

        ②为什么使用字典作为哈希表

        ③字典是用来存什么的

        ④字典中的key和value是用来存什么的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值