✅DAY6 哈希表理论 | 242.有效的字母异位词 | 349. 两个数组的交集 | 202. 快乐数 | 1. 两数之和

小伙伴们共勉~

哈希表理论基础

1. 在 Python 中,hashset 通常指的是**set** 数据结构,set 是一个无序且不重复的元素集合,底层通过哈希表实现。因此,set 支持快速的查找、插入和删除操作,平均时间复杂度为 O(1)

2. 快速查找:set 的查找时间复杂度为 O(1),而列表的查找时间复杂度为 O(n)

3. 取交集

4. 差集:获取集合 A 中有而集合 B 中没有的元素。

5. 并集:获取两个集合的并集。

6. 对称差集:获取两个集合中不重复的元素。

set1 = {1, 2, 3}
set2 = {2, 3, 4}
intersection = set1 & set2  # 输出 {2, 3}

difference = set1.difference(set2)  # 输出 {1}

union = set1.union(set2)  # 输出 {1, 2, 3, 4}

symmetric_diff = set1.symmetric_difference(set2)  # 输出 {1, 4}

242.有效的字母异位词

题目:两个词组成分是否完全一致

解题思路:储存str内容,判断组成内容和个数是否一致

时间复杂度:O(n),其中 n 是字符串的长度。我们遍历了两次字符串 s 和 t。

空间复杂度:O(1),因为字典的空间最多存储 26 个字母的计数。

# 这种做法先把s存起来,减去t里的字符
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        if len(s) != len(t): return False
        res = {}
        for num in s:
            res[num] = res.get(num,0) + 1
        for num in t:
            if num in res:
                res[num] -=1 
                if res[num] == 0 :
                    del res[num]
            else: 
                return False
        return len(res) == 0
# 同理但code更简单一些
class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        # 如果两个字符串的长度不相等,肯定不是异位词
        if len(s) != len(t):
            return False
        
        # 使用两个字典分别统计两个字符串的字符出现次数
        s_count = {}
        t_count = {}
        
        # 遍历字符串 s,记录每个字符的出现次数
        for char in s:
            s_count[char] = s_count.get(char, 0) + 1
        
        # 遍历字符串 t,记录每个字符的出现次数
        for char in t:
            t_count[char] = t_count.get(char, 0) + 1
        
        # 比较两个字典,如果相等,则是异位词
        return s_count == t_count

解题思路:collections.Counter

解释:Counter(s) 会创建一个计数器对象,它会统计 s 中每个字符的出现次数。然后直接将两个计数器对象进行比较,如果它们相等,说明两个字符串是异位词。

时间复杂度:O(n),同样是遍历两次字符串。

空间复杂度:O(1),因为最多存储 26 个字母的计数。

from collections import Counter

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        return Counter(s) == Counter(t)
        

解题思路:

时间复杂度:O(nlog),纯纯暴力

return sorted(s) == sorted(t)

349. 两个数组的交集

解题思路:只考虑了相同的元素。

class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        hash1 = {}
        for char in nums1:
            hash1[char] = hash1.get(char, 0) + 1
        
        res = set()
        for char in nums2:
            if char in hash1:
                res.add(char)
                del hash1[char]
        return list(res)

解题思路:set()应用

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

202. 快乐数

解题思路:先用一个func计算新值。判断是否已经存在,如果==1返回true,else加入到set里,若是在set里返回false

def isHappy(n: int) -> bool:
    visited = set()  # 用set记录已经访问过的数字,避免陷入循环

    # 当 n 还未在 visited 中出现时,继续计算
    while n not in visited:
        if n == 1:  # 如果 n 变成 1,返回 True
            return True
        visited.add(n)  # 将当前数字加入到已访问集合中
        n = sumOfSquare(n)  # 计算当前数字的每位平方和    
    return False  # 如果 n 进入了循环,返回 False

def sumOfSquare(n: int) -> int:
    output = 0
    while n:
        new_digit = (n % 10) ** 2  # 取末位数字的平方
        output += new_digit  # 加到结果中
        n = n // 10  # 去掉末位数字
    return output

解题思路:可以把str(n)的每个元素直接平方求和

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

1. 两数之和

解题思路:两个组成的数一定会见到

时间复杂度:O(n),因为我们只需要遍历一次数组。

空间复杂度:O(n),因为我们需要额外的空间存储已访问过的元素。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        visited = set()

        for i, num in enumerate(nums):
            subtract = target - num
            if subtract in visited:
                return [nums.index(subtract), i]
            visited.add(num)

解题思路:暴力

时间复杂度:O(n²),因为我们用了两个嵌套循环,每次都要检查所有可能的配对。

空间复杂度:O(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)):
                if nums[i] + nums[j] == target:
                    return [i,j]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值