题目解析
题目内容
给定两个按升序排列的帖子ID列表 a 和 b,找出两个列表的公共ID(交集),并按降序返回结果。
输入:两个列表 a 和 b。
输出:交集中的ID按降序排序后的列表。
解题思路
目标:
找出两个列表的交集,即两个列表中都包含的元素。 将交集中的元素按从大到小的顺序排列并返回。
实现步骤:
使用集合计算交集,这会自动去重并高效地找出两个列表中共有的元素。 将交集结果转化为列表,并按降序排列。
关键代码
intersection = set(a) & set(b)
set(a) 和 set(b):将列表转换为集合以便快速操作。
& 运算符:计算两个集合的交集
return sorted(intersection, reverse=True)
sorted(intersection, reverse=True):将交集转化为降序排列的列表。
reverse=True:指示排序函数按从大到小顺序排列。
重点知识
集合运算
Python 的集合操作是处理交集、并集和差集的高效工具。
常用集合方法:
set(a) & set(b):交集。
set(a) | set(b):并集。
set(a) - set(b):差集。
sorted函数
sorted(iterable, key=None, reverse=False):
iterable:待排序对象。
key:排序依据的函数(默认为 None,按元素值排序)。
reverse:若为 True,按降序排列。
性能分析
1. 集合操作的性能
集合(set)在 Python 中基于哈希表实现,具有以下特性:
- 插入、删除、查找操作的时间复杂度为 O(1) 。
- 集合间的交集运算(
&)是逐一遍历两个集合,检查每个元素是否在另一个集合中。
集合交集操作复杂度:
intersection = set(a) & set(b)。
-
步骤:
- 将
a转换为集合set_a:时间复杂度为 O(n),其中 n 是列表a的长度。 - 将
b转换为集合set_b:时间复杂度为 O(m),其中 m 是列表b的长度。 - 计算交集:逐一遍历
set_a和set_b,时间复杂度为 O(min(n,m))。
- 将
-
总复杂度: O(n+m+min(n,m)) 其中,n 和 m 是两个输入列表的长度。
2. 排序操作的性能
排序是另一关键操作:
sorted(intersection, reverse=True)。
-
输入规模:交集的大小记为 k。
-
排序算法:Python 的
sorted()函数底层采用 Timsort,其时间复杂度为:- 最坏情况:O(klogk)
- 平均情况:O(klogk)
-
空间复杂度:Timsort 需要额外的辅助空间,通常为输入大小的线性量,即 O(k)。
3. 整体复杂度分析
输入规模:
- 列表
a长度为 n。 - 列表
b长度为 m。 - 交集大小为 k≤min(n,m)
操作分解:
- 将两个列表转换为集合:O(n+m)。
- 计算集合交集:O(min(n,m))
- 对交集结果排序:O(klogk)
总时间复杂度:
O(n+m+min(n,m)+klogk)O(n + m + \min(n, m) + k \log k)O(n+m+min(n,m)+klogk)
在常见情况下,交集 k 会比 n,m 小得多,因此排序操作对整体复杂度影响较小。
4. 空间复杂度分析
- 集合转换:需要存储两个集合,空间复杂度为 O(n+m)。
- 排序辅助空间:排序需要 O(k)。
- 总空间复杂度: O(n+m+k)
5. 实际性能评估
-
输入较大时(如 n,m=10^6):集合操作的效率很高,处理时间主要受列表长度影响,排序对性能的影响较小。
-
交集较小时(如 k≪n,m):排序耗时几乎可以忽略。
-
极端情况:
- 若无交集(k=0),则排序直接跳过,效率最高。
- 若交集很大(k=min(n,m)),排序可能变成瓶颈。
总结
-
时间复杂度:O(n+m+min(n,m)+klogk)
-
空间复杂度:O(n+m+k)
完整代码
def solution(a, b):
# 将两个列表转换为集合,并计算交集
intersection = set(a) & set(b)
# 将交集转换为列表并按从大到小排序
return sorted(intersection, reverse=True)
if __name__ == '__main__':
print(solution([1, 2, 3, 7], [2, 5, 7]) == [7, 2])
print(solution([1, 4, 8, 10], [2, 4, 8, 10]) == [10, 8, 4])
print(solution([3, 5, 9], [1, 4, 6]) == [])
print(solution([1, 2, 3], [1, 2, 3]) == [3, 2, 1])