LeetCode Hot100数据结构背景知识之集合(Set)Python2026新版

专栏其他内容:

LeetCode Hot100 中 enumerate 函数的妙用(2026.2月版)

LeetCode Hot100数据结构背景知识之列表(List)Python2026新版

LeetCode Hot100数据结构背景知识之元组(Tuple)Python2026新版

LeetCode Hot100数据结构背景知识之集合(Set)Python2026新版

LeetCode Hot100数据结构背景知识之字典(Dictionary)Python2026新版

一、set数据结构背景

LeetCode Hot100中,"去重"和"频繁判断元素是否存在"是高频需求,而我们最熟悉的列表(list),其查找操作的时间复杂度是O(n)------需要遍历整个列表才能确定元素是否存在,去重也需借助循环或字典,效率低下。

集合(set)的出现,正是为了解决这一痛点。它的底层基于**哈希表(Hash Table)**实现,核心逻辑的是:将元素通过哈希函数映射到哈希表的索引位置,若两个元素哈希值相同(即哈希冲突),则通过链表或红黑树解决。这种实现让set的核心操作(添加、删除、查找)平均时间复杂度均为O(1),远优于list的O(n),这也是刷题中优先用set处理去重和查找的核心原因。

二、set核心特性

set的所有特性都围绕**"去重""快速查找"**设计:

  • 无序性 :元素无固定插入顺序,不支持索引和切片(这是与list、tuple的核心区别)。刷题中若需"有序去重",需先通过set去重,再用sorted()排序(如sorted(set(nums))),不可直接遍历set依赖顺序。

  • 唯一性 :自动去除重复元素,无论插入多少个重复值,set中仅保留一个。这是set最常用的特性,比如快速去除数组中的重复元素,一行代码即可实现:unique_nums = set(nums)

  • 可哈希性限制 :set中的元素必须是可哈希对象(如int、str、tuple),不可哈希对象(如list、dict)无法加入set。示例:s = {1, 2} 合法,s = {[1, 2]} 会直接报错------刷题中若需存储多个值,可先将其转为tuple,再加入set。

  • 支持集合运算:内置交集(&)、并集(|)、差集(-)、对称差集(^)等操作,无需手动循环判断,可快速处理"两个集合的关系",对应LeetCode中《两个数组的交集》等高频题目。

三、set常用函数

set的函数均围绕其"可变、唯一、无序"特性设计,核心分为「添加、删除、查询、集合运算、转换」5大类,每类函数都标注了用法、示例和刷题备注,贴合LeetCode实战场景,直接套用即可:

1. 添加类函数(动态补充元素)

  • set.add(x) :向集合中添加单个元素x(x必须是可哈希对象),若x已存在,不做任何操作(避免重复)。 示例:s = {1, 2}s.add(3){1, 2, 3}s.add(2) → 无变化。 【注:常用于遍历过程中动态添加元素(如《两数之和》中,遍历数组时添加元素到set,用于后续快速查找目标补数)。】

  • set.update(iterable) :向集合中添加可迭代对象(如列表、元组、字符串)中的所有元素,自动去重。 示例:s = {1, 2}s.update([2, 3, 4]){1, 2, 3, 4}。 【注:常用于批量添加多个元素(如将两个数组转为set后,快速合并所有元素)。】

2. 删除类函数(安全移除元素)

  • set.remove(x) :从集合中删除元素x,若x不存在,直接报错(KeyError)。 示例:s = {1, 2, 3}s.remove(2){1, 3}s.remove(4) → 报错。 【注:刷题中需确保x存在(如先通过if x in s判断),否则不推荐使用。】

  • set.discard(x) :从集合中删除元素x,若x不存在,不做任何操作(无报错)。 示例:s = {1, 2, 3}s.discard(2){1, 3}s.discard(4) → 无变化。 【注:刷题首选删除函数,避免因元素不存在导致代码报错(如《全排列II》中删除候选元素)。】

  • set.pop() :随机删除集合中的一个元素,并返回该元素(因set无序,无法指定删除位置,建议不要使用 )。 示例:s = {1, 2, 3}s.pop() → 可能返回1、2或3,删除后集合对应减少该元素。

  • set.clear() :清空集合中的所有元素,返回空集合。 示例:s = {1, 2, 3}s.clear()set()

3. 查询类函数(快速判断/统计)

  • len(set) :统计集合中元素的个数,与list、tuple的len()用法一致。 示例:s = {1, 2, 3}len(s) → 3。 【注:高频用法,如《存在重复元素》中,通过len(set(nums)) != len(nums)判断是否有重复元素。】

  • x in set :判断元素x是否在集合中,返回布尔值(True/False),平均时间复杂度O(1)。 示例:s = {1, 2, 3}2 in s → True;4 in s → False。 【注:刷题核心用法,替代list的in操作(O(n)复杂度),如《两数之和》《三数之和》中查找目标元素。】

4. 集合运算类函数(处理两个集合关系)

  • set.intersection(set2) :返回两个集合的交集(等价于set & set2),不修改原集合。 示例:s1 = {1, 2, 3}s2 = {2, 3, 4}s1.intersection(s2){2, 3}。 【注:对应《两个数组的交集》题目,直接获取两个集合的公共元素。】

  • set.union(set2) :返回两个集合的并集(等价于set | set2),不修改原集合,自动去重。 示例:s1 = {1, 2}s2 = {3, 4}s1.union(s2){1, 2, 3, 4}

  • set.difference(set2) :返回set中存在、set2中不存在的元素(等价于set - set2),不修改原集合。 示例:s1 = {1, 2, 3}s2 = {2, 4}s1.difference(s2){1, 3}

  • set.symmetric_difference(set2) :返回两个集合中互不相同的元素(等价于set ^ set2),不修改原集合。 示例:s1 = {1, 2, 3}s2 = {2, 3, 4}s1.symmetric_difference(s2){1, 4}

5. 转换类函数(适配不同场景)

  • tuple(set) / list(set) :将集合转为元组或列表(注意:转换后无序)。 示例:s = {3, 1, 2}list(s)[1, 2, 3](顺序不固定);tuple(s)(1, 2, 3)。 【注:刷题中常用于"去重后需有序"的场景(如先转为set去重,再用sorted()排序,最后转为list)。】

  • set(iterable) :将可迭代对象(如列表、元组)转为集合,自动去重。 示例:nums = [1, 2, 2, 3]s = set(nums){1, 2, 3}。 【注:最高频的用法,快速实现数组去重。】

四、重点补充:集合的a^b运算

在set的集合运算中,a ^ b(对称差集)是高频且易与其他运算混淆的知识点,单独拆解详解,贴合LeetCode刷题场景,帮你彻底避开误区:

  • 运算含义a ^ b 表示「对称差集」,核心是返回"只在a中、或只在b中,不在两个集合的交集中"的所有元素,等价于 (a - b) | (b - a),也等价于 a.symmetric_difference(b)

  • 核心特点:不修改原集合a和b,返回一个新的集合;结果中不包含a和b的公共元素,只保留两者的"独有元素"。

刷题高频示例

示例1:基础用法------提取两个数组的独有元素 a = {1, 2, 3, 4}(对应数组[1,2,3,4]),b = {3, 4, 5, 6}(对应数组[3,4,5,6]a ^ b{1, 2, 5, 6}(1、2仅在a中,5、6仅在b中,3、4是公共元素,不保留)。

示例2:刷题实战场景------《两个数组的差异》 题目要求:给定两个整数数组nums1和nums2,返回所有不在两个数组中同时出现的元素,用集合运算快速求解: nums1 = [1,2,3,4]nums2 = [3,4,5,6] s1 = set(nums1)s2 = set(nums2) result = list(s1 ^ s2)[1,2,5,6]

避坑点

  • ❌ 误区1:混淆a^ba|b------a|b是并集,保留a和b的所有元素(去重),包含公共元素;而a^b不包含公共元素,只保留独有元素。

  • ❌ 误区2:认为a^b会修改原集合------与所有set集合运算一致,a^b返回新集合,原集合a和b的元素不变,刷题中可放心使用,无需担心破坏原数据。 ✅ 技巧:刷题中若遇到"找两个集合的独有元素""排除公共元素"的需求,优先用a^b,比(a - b) | (b - a)更简洁,代码可读性更高。

与其他相关运算的对比a = {1, 2, 3, 4},b = {3, 4, 5, 6}

a & b(交集):只保留公共元素 → {3,4}

a | b(并集):保留所有元素(去重) → {1,2,3,4,5,6}

a - b(差集):只保留a的独有元素 → {1,2}

a ^ b(对称差集):保留a和b的独有元素 → {1,2,5,6}

五、LeetCode Hot100刷题高频用法

用法1:快速去重

场景:题目要求"去除重复元素""判断是否有重复元素"(如《存在重复元素》《删除有序数组中的重复项》)。

示例:判断数组中是否有重复元素,用set一行搞定(LeetCode 217. 存在重复元素):

python 复制代码
def containsDuplicate(nums):
    return len(set(nums)) != len(nums)

解析:将数组转为set后,重复元素会被自动去除,若set长度与原数组不同,则存在重复元素,时间复杂度O(n)(遍历数组转为set),空间复杂度O(n)(存储set),是该题最简洁高效的解法。

用法2:快速查找(替代list的in操作,提升效率)

场景:需要频繁判断"某个元素是否存在"(如《两数之和》《三数之和》《缺失的第一个正数》),用set的in操作替代list的in操作,将时间复杂度从O(n)降至O(1)。

示例:《两数之和》优化解法(LeetCode 1. 两数之和),用set替代dict,简化代码:

python 复制代码
def twoSum(nums, target):
    s = set()
    for i, num in enumerate(nums):
        complement = target - num
        if complement in s:  # O(1)查找,比list的in操作快得多
            return [nums.index(complement), i]
        s.add(num)

用法3:集合运算(处理两个数组的关系)

核心运算示例:

  • 《两个数组的交集》(LeetCode 349):返回两个数组的公共元素,用交集运算:
python 复制代码
def intersection(nums1, nums2): return list(set(nums1) & set(nums2))
  • 《两个数组的差集》:返回nums1中存在、nums2中不存在的元素,用差集运算:
python 复制代码
def difference(nums1, nums2): return list(set(nums1) - set(nums2))
  • 提取两个数组的独有元素:用对称差集运算a^b,如前面的实战示例。

用法4:辅助去重(回溯/排列组合题目)

场景:《全排列II》《子集II》等题目,需要避免重复的排列或子集,用set存储中间结果,自动去重,简化剪枝逻辑(无需手动判断重复元素)。

示例:《全排列II》(LeetCode 47)辅助去重思路:

python 复制代码
def permuteUnique(nums):
    res = []
    def backtrack(path, used):
        if len(path) == len(nums):
            res.append(path.copy())
            return
        s = set()  # 用set存储当前层的候选元素,避免重复选择
        for i in range(len(nums)):
            if used[i] or nums[i] in s:
                continue
            s.add(nums[i])
            used[i] = True
            path.append(nums[i])
            backtrack(path, used)
            path.pop()
            used[i] = False
    backtrack([], [False]*len(nums))
    return res

解析:用set存储当前递归层的候选元素,若元素已在set中,说明已选择过,跳过即可,无需复杂的剪枝判断,大幅简化代码。

六、高频误区

  • ❌ 误区1:依赖set的顺序------set是无序的,若刷题中需要"有序输出",需先转为set去重,再用sorted()排序,示例:sorted(set(nums)),不可直接遍历set后输出(顺序不确定,会导致答案错误)。

  • ❌ 误区2:尝试将不可哈希对象加入set------list、dict无法作为set的元素,若需存储多个值(如坐标),可先转为tuple,示例:s.add((1, 2)) 合法,s.add([1, 2]) 报错。

  • ❌ 误区3:混淆remove()和discard()------remove(x)若x不存在会报错,discard(x)不会,刷题中优先用discard(x),尤其是不确定元素是否存在的场景(如删除候选元素)。

  • ❌ 误区4:过度使用set------set虽高效,但需额外占用内存(空间复杂度O(n)),若题目要求"空间复杂度O(1)"(如《删除有序数组中的重复项》进阶要求),则不可用set,需用双指针法。

相关推荐
参.商.5 小时前
【Day 27】121.买卖股票的最佳时机 122.买卖股票的最佳时机II
leetcode·golang
踢足球09295 小时前
寒假打卡:2026-2-8
数据结构·算法
IT猿手5 小时前
基于强化学习的多算子差分进化路径规划算法QSMODE的机器人路径规划问题研究,提供MATLAB代码
算法·matlab·机器人
千逐-沐风5 小时前
SMU-ACM2026冬训周报3rd
算法
老赵说5 小时前
Java基础数据结构全面解析与实战指南:从小白到高手的通关秘籍
数据结构
怒放吧德德5 小时前
Python3基础:基础实战巩固,从“会用”到“活用”
后端·python
aiguangyuan5 小时前
基于BERT的中文命名实体识别实战解析
人工智能·python·nlp
喵手5 小时前
Python爬虫实战:知识挖掘机 - 知乎问答与专栏文章的深度分页采集系统(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集知乎问答与专栏文章·采集知乎数据·采集知乎数据存储sqlite
铉铉这波能秀5 小时前
LeetCode Hot100数据结构背景知识之元组(Tuple)Python2026新版
数据结构·python·算法·leetcode·元组·tuple