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

51 阅读3分钟

问题背景

小S正在帮助她的朋友们建立一个搜索引擎,为了提高搜索效率,她决定使用倒排索引。倒排索引是一种常见的数据结构,用于快速查找包含特定单词的文档。每个单词都关联一个文档ID的列表,这些文档包含该单词,并且ID按从小到大的顺序排列。例如,单词“夏天”可能出现在文档1、文档3和文档7中,那么这个单词的倒排链就是 [1, 3, 7]

问题描述

给定两个单词的倒排链数组 a 和 b,要求找出同时包含这两个单词的文档ID,并按从大到小的顺序返回结果。例如,如果单词“夏天”的倒排链是 [1, 2, 3, 7],而单词“海滩”的倒排链是 [2, 5, 7],那么同时包含这两个单词的文档ID是 [2, 7],按从大到小的顺序返回结果为 [7, 2]

解题思路

  1. 理解问题:我们需要找出两个有序数组的交集,并将结果按从大到小的顺序返回。

  2. 数据结构选择:由于输入的数组是有序的,我们可以使用双指针法来高效地找出交集。

  3. 算法步骤

    • 初始化两个指针,分别指向两个数组的末尾。

    • 比较两个指针所指的元素:

      • 如果两个元素相等,则将该元素加入结果列表,并将两个指针都向前移动。
      • 如果 a 中的元素大于 b 中的元素,则移动 a 的指针。
      • 如果 b 中的元素大于 a 中的元素,则移动 b 的指针。
    • 重复上述步骤,直到其中一个指针越界。

  4. 结果列表:由于我们从后向前遍历,结果列表中的元素已经是按从大到小的顺序排列的。

代码实现

python

def solution(a, b):

    result = []

    i, j = len(a) - 1, len(b) - 1

    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

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])

代码解释

  1. 双指针法:我们从两个列表的末尾开始,比较两个指针所指的元素。

    • 如果两个元素相等,则将该元素加入结果列表,并将两个指针都向前移动。
    • 如果 a 中的元素大于 b 中的元素,则移动 a 的指针。
    • 如果 b 中的元素大于 a 中的元素,则移动 b 的指针。
  2. 结果列表:由于我们从后向前遍历,结果列表中的元素已经是按从大到小的顺序排列的。

测试

在 main 方法中,我们使用题目中提供的测试样例来验证代码的正确性。

复杂度分析

  • 时间复杂度:O(n + m),其中 n 和 m 分别是两个数组的长度。因为我们只需要遍历两个数组一次。
  • 空间复杂度:O(min(n, m)),在最坏情况下,结果列表的大小不会超过两个数组中较小的那个。

总结

这道题目通过使用双指针法,我们可以高效地找出两个有序数组的交集,并将结果按从大到小的顺序返回。双指针法是一种常见的算法技巧,适用于处理有序数组或链表的问题。通过合理地选择数据结构和算法,我们可以在保证时间复杂度的同时,有效地解决问题。

在实际应用中,倒排索引和双指针法都是非常有用的工具,特别是在搜索引擎和数据库查询优化中。通过理解和掌握这些技术,我们可以更好地设计和实现高效的算法,从而提升系统的性能和用户体验。