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

98 阅读3分钟

问题描述

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

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

第一种

思路分析

需要找出两个有序列表 a 和 b 的交集,将交集结果转换为列表,并将结果按从大到小的顺序返回。

算法步骤

  1. 转换为集合:将列表 a 和 b 分别转换为集合。
  2. 求交集:使用集合的交集操作 & 找到两个集合的交集。
  3. 转换为列表并排序:将交集结果转换为列表,并使用 sorted 函数按降序排序。

代码实现

def solution(a, b):
    # write code here
    common = set(a) & set(b)
    return sorted(list(common), reverse=True)
    #return []

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 是有序列表,可以考虑使用双指针法来直接找到交集,这样可以避免集合转换和排序的开销。
  2. 减少不必要的转换:直接在有序列表上操作,可以减少集合和列表之间的转换次数。

算法步骤

  1. 初始化指针:使用两个指针分别指向 a 和 b 的开始位置。

  2. 查找交集

    • 如果 a[i] 等于 b[j],则将该元素加入结果集,并移动两个指针。
    • 如果 a[i] 小于 b[j],则移动 a 的指针。
    • 如果 a[i] 大于 b[j],则移动 b 的指针。
  3. 排序结果:将结果集按从大到小的顺序排序。

代码实现

def solution(a, b):
    # write code here
        # 初始化指针
    i, j = 0, 0
    result = []
    
    # 查找交集
    while i < len(a) and j < len(b):
        if a[i] == b[j]:
            result.append(a[i])
            i += 1
            j += 1
        elif a[i] < b[j]:
            i += 1
        else:
            j += 1
    
    # 将结果按从大到小的顺序排序
    result.sort(reverse=True)
    
    return result
    #return []

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