数据结构 · #7 / 11

集合

唯一性 + 快速成员检测

为什么重要

集合能去除重复项,并提供平均 O(1) 的成员检测——这对许多数据结构与算法问题来说堪称完美。

核心思想

集合是一袋唯一、可哈希、无序的元素。来自学校的运算:| 并集,& 交集,- 差集,^ 对称差。

试一试

去重与成员检测:

nums = [1, 1, 2, 3, 3, 5, 5, 7]
unique = set(nums)
print(unique, "size:", len(unique))

print(5 in unique)   # O(1) average
print(9 in unique)
not loaded

集合代数:

a = {"red", "green", "blue", "yellow"}
b = {"green", "blue", "purple"}
print("union        ", a | b)
print("intersection ", a & b)
print("a only       ", a - b)
print("xor          ", a ^ b)
not loaded

一道经典的面试题——第一个重复出现的字符:

def first_repeat(s):
  seen = set()
  for ch in s:
      if ch in seen:
          return ch
      seen.add(ch)
  return None

for w in ["abcdea", "abcde", "swiss"]:
  print(w, "->", first_repeat(w))
not loaded

核心方法

| 方法 | 作用 | 示例 | | --- | --- | --- | | add(x) | 添加一个 | st.add(3) | | update(iter) | 添加多个 | st.update([4,5]) | | remove(x) | 移除;不存在则报错 | st.remove(2) | | discard(x) | 安全移除 | st.discard(2) | | pop() | 移除任意一个 | st.pop() | | clear() | 移除全部 | st.clear() | | copy() | 浅拷贝 | st.copy() |

子集 / 超集检查

A <= B   # subset
A <  B   # proper subset
A >= B   # superset

集合推导式与 frozenset

squares = {x*x for x in range(5)}   # set comprehension
fs = frozenset([1, 2, 3])           # immutable, hashable set

快速检查

小练习

该做与不该做

深入一点——复杂度速览
  • 成员检测:平均约 O(1)
  • 集合代数(|&-^):O(n)

常见错误

关键要点