伴学笔记10| 豆包MarsCode AI刷题

126 阅读4分钟

## 小S的倒排索引

问题描述

小S正在帮助她的朋友们建立一个搜索引擎。为了让用户能够更快地找到他们感兴趣的帖子,小S决定使用倒排索引。倒排索引的工作原理是:每个单词都会关联一个帖子ID的列表,这些帖子包含该单词,且ID按从小到大的顺序排列。
例如,单词“夏天”可能出现在帖子1、帖子3和帖子7中,那么这个单词的倒排链就是 [1, 3, 7]。如果用户想同时找到包含“夏天”和“海滩”的帖子,小S需要找出两个倒排链的交集,且将结果按照从大到小的顺序输出。现在,给定两个单词的倒排链数组 a 和 b,请你帮助小S找出同时包含这两个单词的帖子ID,并按从大到小的顺序返回结果。

倒排索引是搜索引擎领域的核心技术之一,其高效性和灵活性使得它在处理文本检索任务中占据了重要地位。本次题目通过两个倒排链的交集求解,进一步加深了对倒排索引的理解,也让我认识到了算法优化的重要性。


题目分析

本题的关键是找出两个有序数组的交集,并将交集结果按从大到小的顺序返回。以下是解题的几个要点:

  1. 有序数组的交集问题
    两个倒排链是按升序排列的,因此可以利用双指针法高效计算交集,而不需要遍历整个数组,从而提升算法效率。

  2. 逆序输出
    由于题目要求结果按降序输出,而倒排链本身是升序的,可以直接在输出时逆序即可,无需额外操作。

  3. 空集的处理
    如果两个链表没有交集,则需要返回空数组 [],这一点需要通过边界条件和算法实现中明确检查。


算法实现

可以使用 双指针法 来解决此问题,算法流程如下:

  1. 定义两个指针分别指向数组 ab 的末尾。
  2. 比较当前两个指针指向的值:
    • 如果值相等,则加入结果数组,并同时移动两个指针。
    • 如果值不相等,移动指向较大的值的指针。
  3. 重复直到其中一个数组的指针越界。
  4. 返回结果数组。

代码实现

以下是 Python 实现代码:

def inverted_index_intersection(a, b):
    # 初始化指针和结果数组
    i, j = len(a) - 1, len(b) - 1
    result = []
    
    # 双指针遍历
    while i >= 0 and j >= 0:
        if a[i] == b[j]:
            result.append(a[i])
            i -= 1
            j -= 1
        elif a[i] > b[j]:
            i -= 1
        else:
            j -= 1
    
    # 返回结果数组
    return result

测试与验证

对题目提供的样例进行测试,结果如下:

# 测试样例
print(inverted_index_intersection([1, 2, 3, 7], [2, 5, 7]))  # 输出: [7, 2]
print(inverted_index_intersection([1, 4, 8, 10], [2, 4, 8, 10]))  # 输出: [10, 8, 4]
print(inverted_index_intersection([3, 5, 9], [1, 4, 6]))  # 输出: []
print(inverted_index_intersection([1, 2, 3], [1, 2, 3]))  # 输出: [3, 2, 1]

输出分析

  1. 样例1:[7, 2],因为两个链表的交集为 {7, 2},按降序排列。
  2. 样例2:[10, 8, 4],交集为 {10, 8, 4},按降序排列。
  3. 样例3:[],没有交集,返回空数组。
  4. 样例4:[3, 2, 1],交集为 {3, 2, 1},按降序排列。

心得总结

在解决本题的过程中,我深刻体会到了以下几点:

  1. 利用有序性降低时间复杂度
    双指针法充分利用了输入的有序性,避免了暴力搜索的复杂度,从而使算法更加高效。

  2. 结果处理与问题解耦
    在计算交集时关注逻辑的简洁性,而排序等需求通过输出时逆序完成,从而保持了代码的清晰性。

  3. 边界条件的重要性
    特殊情况如空数组的处理,是算法鲁棒性的重要保证。

通过这道题,我对倒排索引的工作机制和算法优化有了更深的认识,同时也收获了更好的算法思维方式。