问题描述
小S正在帮助她的朋友们建立一个搜索引擎。为了让用户能够更快地找到他们感兴趣的帖子,小S决定使用倒排索引。倒排索引的工作原理是:每个单词都会关联一个帖子ID的列表,这些帖子包含该单词,且ID按从小到大的顺序排列。
例如,单词“夏天”可能出现在帖子1、帖子3和帖子7中,那么这个单词的倒排链就是 [1, 3, 7]。如果用户想同时找到包含“夏天”和“海滩”的帖子,小S需要找出两个倒排链的交集,且将结果按照从大到小的顺序输出。现在,给定两个单词的倒排链数组 a 和 b,请你帮助小S找出同时包含这两个单词的帖子ID,并按从大到小的顺序返回结果。
问题背景
原本的问题是搜索引擎中倒排索引的一个实际应用场景。倒排索引是一种索引方法,简单来说,它能够将文档中出现的每个单词映射到包含该单词的文档列表中,使得搜索引擎能够快速检索包含特定单词或单词组合的文档。
程序分析
输入:两个单词的倒排链数组a和b。这些数组包含帖子ID,表示包含对应关键词的帖子。
输出:一个列表,包含同时包含这两个关键词的所有帖子ID,且这些ID按照从大到小的顺序排列。
运行顺序:
- 转换为集合:将两个倒排链数组
a和b转换为集合,以便快速找出它们的交集。 - 找出交集:使用集合的交集操作
&找出同时出现在两个倒排链中的帖子ID。 - 排序:将交集结果转换回列表,并使用排序函数(
sorted)按照从大到小的顺序排列这些ID。 - 返回结果:返回排序后的列表。
在python中,以上操作都有现成的程序,如用set()对ID集合进行成员检查并转换为集合,用intersection()对集合进行交集等,熟悉函数语句就不难写出程序。
测试样例
输入:a = [1, 2, 3, 7], b = [2, 5, 7]
输出:[7, 2]
输入:a = [1, 4, 8, 10], b = [2, 4, 8, 10]
输出:[10, 8, 4]
输入:a = [3, 5, 9], b = [1, 4, 6]
输出:[]
输入:a = [1, 2, 3], b = [1, 2, 3]
输出:[3, 2, 1]
代码实现
def solution(a, b):
intersection = set(a) & set(b)
# 将两个ID列表转换为集合的形式,并用&运算找出交集
result = sorted(intersection, reverse=True)
# 将交集转换为列表并进行倒序排序
return result
if __name__ == '__main__':
print(solution([1, 2, 3, 7], [2, 5, 7]) == [7, 2]) # 输出: [7, 2]
print(solution([1, 4, 8, 10], [2, 4, 8, 10]) == [10, 8, 4]) # 输出: [10, 8, 4]
print(solution([3, 5, 9], [1, 4, 6]) == []) # 输出: []
print(solution([1, 2, 3], [1, 2, 3]) == [3, 2, 1]) # 输出: [3, 2, 1]
时间复杂度
• 集合转换:由于set()函数集合在添加元素时会检查元素的重复性,每次操作的时间复杂度是,所以将列表转换为集合的时间复杂度是,其中n和m分别是列表a和b的长度。
• 求交集:求两个集合的交集的时间复杂度是,因为集合的内置交集操作是基于哈希表实现的,每个元素的查找、插入和删除操作平均是O。
• 排序:对交集结果进行排序的时间复杂度是,其中k是交集结果中元素的数量。
综上,该程序整体时间复杂度化简后是。
空间复杂度
• 集合转换:存储两个列表中的所有唯一元素,空间复杂度是O(n+m)。
• 求交集:交集操作本身不需要额外的空间,但是结果需要存储,最坏情况下,如果两个集合完全相同,那么空间复杂度是O(n+m)。
• 排序:排序操作通常需要O(k)的额外空间,其中k是交集结果中元素的数量。
综上,整个程序的空间复杂度主要由集合和排序决定,空间复杂度是O(n+m+k)。