问题描述
小S正在帮助她的朋友们建立一个搜索引擎。为了让用户能够更快地找到他们感兴趣的帖子,小S决定使用倒排索引。倒排索引的工作原理是:每个单词都会关联一个帖子ID的列表,这些帖子包含该单词,且ID按从小到大的顺序排列。
例如,单词“夏天”可能出现在帖子1、帖子3和帖子7中,那么这个单词的倒排链就是
[1, 3, 7]。如果用户想同时找到包含“夏天”和“海滩”的帖子,小S需要找出两个倒排链的交集,且将结果按照从大到小的顺序输出。现在,给定两个单词的倒排链数组a和b,请你帮助小S找出同时包含这两个单词的帖子ID,并按从大到小的顺序返回结果。
第一种
思路分析
需要找出两个有序列表 a 和 b 的交集,将交集结果转换为列表,并将结果按从大到小的顺序返回。
算法步骤
- 转换为集合:将列表
a和b分别转换为集合。 - 求交集:使用集合的交集操作
&找到两个集合的交集。 - 转换为列表并排序:将交集结果转换为列表,并使用
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])
代码分析
- 优点:使用集合求交集非常高效,适合处理大数据量的情况。
- 缺点:集合是无序的,因此在求交集后需要额外的排序步骤。
第二种(改进版)
- 利用有序列表的特性:由于
a和b是有序列表,可以考虑使用双指针法来直接找到交集,这样可以避免集合转换和排序的开销。 - 减少不必要的转换:直接在有序列表上操作,可以减少集合和列表之间的转换次数。
算法步骤
-
初始化指针:使用两个指针分别指向
a和b的开始位置。 -
查找交集:
- 如果
a[i]等于b[j],则将该元素加入结果集,并移动两个指针。 - 如果
a[i]小于b[j],则移动a的指针。 - 如果
a[i]大于b[j],则移动b的指针。
- 如果
-
排序结果:将结果集按从大到小的顺序排序。
代码实现
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])