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

173 阅读5分钟

使用倒排索引实现帖子搜索的交集查询

在开发搜索引擎时,为了提高用户查找信息的效率,小S设计了一个倒排索引(Inverted Index)系统。倒排索引的核心思想是为每个单词关联一个帖子ID的有序列表,这些帖子包含该单词。当用户查询多个关键词时,我们需要找到包含所有关键词的帖子集合,并按照特定顺序输出结果。

本文将通过一个具体问题讲解如何实现倒排索引的交集查询。


问题描述

给定两个单词的倒排链数组 ab,需要找出同时包含这两个单词的帖子ID,并将结果按照从大到小的顺序返回。

示例

输入输出样例

样例1:

输入: a = [1, 2, 3, 7], b = [2, 5, 7]
输出: [7, 2]

样例2:

输入: a = [1, 4, 8, 10], b = [2, 4, 8, 10]
输出: [10, 8, 4]

样例3:

输入: a = [3, 5, 9], b = [1, 4, 6]
输出: []

样例4:

输入: a = [1, 2, 3], b = [1, 2, 3]
输出: [3, 2, 1]

解题思路

1. 集合交集运算

首先,两个倒排链是有序数组。为了找出它们的交集,可以将两个数组转化为集合,使用集合的交集运算 (&) 来快速计算出公共元素。

2. 排序

计算出的交集结果需要按从大到小的顺序输出。可以使用 Python 内置的 sorted() 函数,设置参数 reverse=True 实现降序排列。


实现代码

以下是完整的 Python 实现代码:

def solution(a, b):
    # 使用集合的交集运算找到公共元素
    intersection = set(a) & set(b)
    # 将结果按从大到小的顺序排列
    intersection = sorted(intersection, reverse=True)
    return intersection

# 测试样例
if __name__ == '__main__':
    print(solution([1, 2, 3, 7], [2, 5, 7]) == [7, 2])   # 样例1
    print(solution([1, 4, 8, 10], [2, 4, 8, 10]) == [10, 8, 4])  # 样例2
    print(solution([3, 5, 9], [1, 4, 6]) == [])          # 样例3
    print(solution([1, 2, 3], [1, 2, 3]) == [3, 2, 1])   # 样例4

代码解析

1. 集合交集

代码中的 set(a) & set(b) 使用集合操作符 & 计算出两个数组的交集。集合操作的效率很高,可以快速找到公共元素。

示例:

a = [1, 2, 3, 7]
b = [2, 5, 7]
intersection = set(a) & set(b)  # 输出 {2, 7}

2. 排序

通过 sorted(intersection, reverse=True) 对交集结果进行降序排序,返回一个列表。

示例:

intersection = {2, 7}
sorted_result = sorted(intersection, reverse=True)  # 输出 [7, 2]

3. 返回结果

最终返回的是一个按降序排列的列表形式,符合题目要求。


测试结果

样例测试

我们使用上述代码对题目给出的所有样例进行了测试,结果如下:

solution([1, 2, 3, 7], [2, 5, 7])   # 输出: [7, 2]
solution([1, 4, 8, 10], [2, 4, 8, 10])  # 输出: [10, 8, 4]
solution([3, 5, 9], [1, 4, 6])          # 输出: []
solution([1, 2, 3], [1, 2, 3])          # 输出: [3, 2, 1]

时间复杂度分析

  1. 集合操作: 转化为集合并求交集的时间复杂度为 (O(n + m)),其中 (n) 和 (m) 分别是数组 ab 的长度。
  2. 排序: 排序的时间复杂度为 (O(k \log k)),其中 (k) 是交集的大小。

综上,总时间复杂度为 (O(n + m + k \log k)),在实际场景中性能较优。


总结

  1. 简单的方法通常是最优的:
    在解决问题时,我一开始也考虑过用双指针遍历两个数组来找交集。但后来发现,利用集合交集运算可以大幅简化代码,同时性能也不逊色。这让我意识到,在面对问题时,选择最直接的工具往往会带来更高效的解决方案。

  2. 对内置函数的熟悉程度很重要:
    Python 提供了丰富的内置函数,例如 setsorted(),它们能够显著提高开发效率。熟悉这些工具,不仅能节省编写代码的时间,还能让代码更容易阅读和维护。

  3. 写测试用例的重要性:
    每当完成一个功能后,验证代码的准确性至关重要。通过编写测试用例,我可以在多种输入场景下验证代码是否健壮,这样的习惯在实际项目中非常有用。


使用豆包AI工具的好处

  1. 快速发现问题的解决思路:
    使用豆包AI工具时,我能够快速找到问题的核心解决方法。它提供的解答逻辑清晰、结构分明,可以让我更专注于代码实现和优化。

  2. 节省时间:
    在调试或实现复杂功能时,豆包AI可以提供直接可运行的代码框架或提示,极大地缩短了开发时间。特别是在处理类似倒排索引这类通用问题时,效率提升尤为显著。

  3. 帮助提升思维能力:
    虽然豆包AI给出了答案,但它也让我在阅读代码和优化解决方案时学到了很多新的技巧。例如,如何平衡代码的效率与可读性、如何巧妙利用内置函数等。

  4. 知识的补充与验证:
    在解决这个问题的过程中,豆包AI工具不仅帮助验证了我的想法,还让我掌握了更优的实现方式。这种验证机制让我对最终的代码质量更有信心。


结语

通过解决这个问题,我不仅巩固了集合操作和排序的知识,还深刻体会到算法问题的解决方法可以多种多样,但找到最简洁、最优雅的方式才是编程的核心。而豆包AI工具则是高效解决问题和提升编程能力的得力助手。它不仅节省了时间,也让我有机会去深挖背后的算法逻辑。这次经验也让我更有信心去面对更复杂的问题挑战!