问题分析
给定两个倒排索引数组 a 和 b,分别代表单词出现的帖子ID。我们的任务是找出同时包含这两个单词的帖子ID,并按照从大到小的顺序返回结果。
解决思路
-
理解倒排链:
- 数组
a和b分别代表了两个单词的帖子ID列表。每个数组是升序排列的。 - 我们的目标是找出两个数组的交集,即同时出现在
a和b中的帖子ID。
- 数组
-
交集的寻找:
- 由于
a和b都是升序排列的,我们可以使用双指针法高效地求解交集。 - 双指针法:两个指针分别指向
a和b的开头。如果指针指向的元素相同,就将该元素加入结果列表并移动两个指针。如果指向的元素不相同,则移动值较小的那个指针,直到两个指针都走完。
- 由于
-
返回结果:
- 交集求出来之后,按题目要求需要将结果从大到小排序。可以通过反转结果列表来实现。
算法步骤
-
初始化两个指针:分别指向数组
a和b的开始位置。 -
双指针遍历:
- 比较指针指向的元素。
- 如果相等,将该元素加入结果列表,并同时移动两个指针。
- 如果不相等,移动指向较小值的指针,继续比较。
-
反转结果:因为要按从大到小的顺序返回,所以最终将交集结果反转。
-
返回结果。
代码实现
pythonCopy Code
def find_common_posts(a, b):
# 双指针初始化
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
# 结果需要从大到小排序
return result[::-1]
# 输入读取
a = list(map(int, input().split()))
b = list(map(int, input().split()))
# 输出结果
print(find_common_posts(a, b))
解释
-
双指针法:我们有两个指针
i和j,分别指向数组a和b的当前元素。每次比较a[i]和b[j]:- 如果相等,说明这是一个公共帖子ID,加入
result列表,两个指针都向后移动。 - 如果
a[i]小于b[j],说明a[i]没有在b中出现,因此只移动i。 - 如果
a[i]大于b[j],说明b[j]没有在a中出现,因此只移动j。
- 如果相等,说明这是一个公共帖子ID,加入
-
反转结果:最终的结果是升序的,而题目要求从大到小,所以使用
result[::-1]将结果反转。
复杂度分析
-
时间复杂度:
- 双指针遍历:由于每次移动一个指针,最多遍历一遍
a和b,所以时间复杂度为O(n + m),其中n和m分别是数组a和b的长度。 - 反转结果:反转一个大小为
min(n, m)的列表,时间复杂度是O(min(n, m))。 - 因此,整体时间复杂度是
O(n + m)。
- 双指针遍历:由于每次移动一个指针,最多遍历一遍
-
空间复杂度:
- 我们使用了一个额外的列表
result存储交集,空间复杂度是O(min(n, m))。
- 我们使用了一个额外的列表
示例
输入:
Copy Code
1 2 3 5 6
2 3 4 5 7
输出:
Copy Code
[5, 3, 2]
解释:
- 数组
a= [1, 2, 3, 5, 6] - 数组
b= [2, 3, 4, 5, 7] - 交集是 [2, 3, 5]
- 反转后返回结果 [5, 3, 2]
优化和总结
- 时间效率:使用双指针法能在线性时间内找到交集,避免了使用暴力方法(例如嵌套循环)的高时间复杂度。
- 空间效率:通过在原地修改和只使用必要的额外空间,我们保证了空间复杂度较低。