小S的倒排索引 | 豆包MarsCode AI刷题

104 阅读4分钟

问题描述

小S正在帮助她的朋友们建立一个搜索引擎。为了让用户能够更快地找到他们感兴趣的帖子,小S决定使用倒排索引。倒排索引的工作原理是:每个单词都会关联一个帖子ID的列表,这些帖子包含该单词,且ID按从小到大的顺序排列。

例如,单词“夏天”可能出现在帖子1、帖子3和帖子7中,那么这个单词的倒排链就是 [1, 3, 7]。如果用户想同时找到包含“夏天”和“海滩”的帖子,小S需要找出两个倒排链的交集,且将结果按照从大到小的顺序输出。现在,给定两个单词的倒排链数组 a 和 b,请你帮助小S找出同时包含这两个单词的帖子ID,并按从大到小的顺序返回结果。

问题背景

原本的问题是搜索引擎中倒排索引的一个实际应用场景。倒排索引是一种索引方法,简单来说,它能够将文档中出现的每个单词映射到包含该单词的文档列表中,使得搜索引擎能够快速检索包含特定单词或单词组合的文档。

程序分析

输入:两个单词的倒排链数组ab。这些数组包含帖子ID,表示包含对应关键词的帖子。

输出:一个列表,包含同时包含这两个关键词的所有帖子ID,且这些ID按照从大到小的顺序排列。

运行顺序:

  1. 转换为集合:将两个倒排链数组ab转换为集合,以便快速找出它们的交集。
  2. 找出交集:使用集合的交集操作&找出同时出现在两个倒排链中的帖子ID。
  3. 排序:将交集结果转换回列表,并使用排序函数(sorted)按照从大到小的顺序排列这些ID。
  4. 返回结果:返回排序后的列表。

在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()函数集合在添加元素时会检查元素的重复性,每次操作的时间复杂度是O(1)O(1),所以将列表转换为集合的时间复杂度是O(n+m)O(n+m),其中n和m分别是列表a和b的长度。

• 求交集:求两个集合的交集的时间复杂度是O(min(n,m))O(min(n,m)),因为集合的内置交集操作是基于哈希表实现的,每个元素的查找、插入和删除操作平均是O(1)(1)

• 排序:对交集结果进行排序的时间复杂度是O(klogk)O(k log k),其中k是交集结果中元素的数量。

综上,该程序整体时间复杂度化简后是O(n+m+klogk)O(n+m+k log k)

空间复杂度

• 集合转换:存储两个列表中的所有唯一元素,空间复杂度是O(n+m)。

• 求交集:交集操作本身不需要额外的空间,但是结果需要存储,最坏情况下,如果两个集合完全相同,那么空间复杂度是O(n+m)。

• 排序:排序操作通常需要O(k)的额外空间,其中k是交集结果中元素的数量。

综上,整个程序的空间复杂度主要由集合和排序决定,空间复杂度是O(n+m+k)。