代码随想录|Day05|哈希表01|242.有效的字母异位词、349. 两个数组的交集、202. 快乐数 、1. 两数之和

文章介绍了如何使用字典和列表数据结构判断字符串是否为字母异位词,以及两种方法处理两个数组交集的问题,同时讨论了快乐数的判断算法。展示了不同场景下的时间复杂度和空间复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

242.有效的字母异位词

给定两个字符串 s 和 t ,若 s 和 t 中每个字符出现的次数都相同,则互为字母异位词。

由于要记录字符出现的次数,给出两种记数方式:字典和列表

字典大家都非常熟悉,字符作为 key,构建位置映射,并对应一个 val

这样我们就能记录每个字符出现的次数,最后遍历 s 和 t,对比两个字典即可。

列表并没有这种结构,如何构建字符和位置的对应关系呢?

使用字符的 ASCII 码值来表示他们在列表中的 index。例如,a 映射到 index 0b 映射到 index 1,以此类推,直到 z 映射到 index 25

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        #构建字典
        countS, countT = {}, {}
        # 遍历字符串
        for char in s:
            if char in countS:
                countS[char] += 1
            else:
                countS[char] = 1
        
        for char in t:
            if char in countT:
                countT[char] += 1
            else:
                countT[char] = 1
        # 对比字典
        return countS == countT
# 时间复杂度:
# O(n)
# 空间复杂度:
# O(1)
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        # 构建列表
        count = [0] * 26
        # 遍历 s,在对应位置上记数 +1
        for char in s:
            index = ord(char) - ord('a')
            count[index] += 1
        # 遍历 t,在对应位置上记数 -1
        for char in t:
            index = ord(char) - ord('a')
            count[index] -= 1
        # 如果互为字母异位词,则列表每个元素都应该为0
        for i in count:
            if i != 0:
                return False

        return True
# 时间复杂度:
# O(n)
# 空间复杂度:
# O(1)

 349. 两个数组的交集

此处提供两个思路:

1. 内置函数,效率并不低

2. 双指针,优化空间复杂度

双指针思路:现将列表排序,接着分别定义一个指针指向列表首位,每次对比指针所指元素,如果相等则放入事先定义的 set

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        # 内置函数
        # set给两列表去重
        set1 = set(nums1)
        set2 = set(nums2)
        # 求出交集
        return list(set1 & set2)
# 时间复杂度:
# O(n)
# 空间复杂度:
# O(n)
class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:        
        # 双指针
        nums1.sort()
        nums2.sort()

        index1, index2 = 0, 0

        res = set()
        
        while index1 < len(nums1) and index2 < len(nums2):
            
            if nums1[index1] < nums2[index2]:
                index1 += 1
            elif nums1[index1] > nums2[index2]:
                index2 += 1
            else:
                res.add(nums1[index1])
                index1 += 1
                index2 += 1

        return list(res)
# 时间复杂度:
# O(n)
# 空间复杂度:
# O(1)

202. 快乐数

判断是否为快乐数时,在计算各位数平方和的循环中,有以下两个观察:
1. 某平方和重复出现,则说明此数字会无限循环,一定不是快乐数

2. 如果平方和为 1,则说明为快乐数

class Solution:
    def isHappy(self, n: int) -> bool:

        def get_next_number(number):
            return sum(int(i) **2 for i in str(number))
        
        seen_numbers = []
        
        while n not in seen_numbers:
            if n == 1:
                return True
            else:
                seen_numbers.append(n)
                n = get_next_number(n)
        
        return False

1. 两数之和

暴力:双层for循环遍历所有的情况

哈希法:通过一次遍历数组,对于每个元素 x,检查 target - x 是否已经在之前遍历的元素中出现过(即是否已存在于哈希表中)。如果存在,那么就找到了一对符合条件的元素,并可以直接返回它们的下标。这种方法的时间复杂度可以降低到 O(n)

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]
# 时间复杂度:
# O(n²)
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        
        # 创建字典记录已遍历元素,key为元素值,val为索引
        seen = {}

        for index, num in enumerate(nums):
            # 对于每个遍历的元素,在seen中寻找其补数是否已被遍历过
            complement = target - num

            if complement in seen:
                return [seen[complement], index]

            else: seen[num] = index
# 时间复杂度:
# O(n)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值