解题思路
问题理解
我们需要找出两个有序数组 a 和 b 的交集,并将结果按从大到小的顺序输出。交集的定义是两个数组中都出现的元素。
数据结构选择
由于输入的两个数组是有序的,我们可以利用这一特性来优化查找交集的过程。使用双指针法是一个不错的选择,因为它可以在一次遍历中完成交集的查找,时间复杂度为 O(n + m),其中 n 和 m 分别是两个数组的长度。
算法步骤
- 初始化指针:设置两个指针
i和j,分别指向数组a和b的开头。 - 遍历数组:使用一个循环,当两个指针都没有超出各自数组的范围时,进行以下操作:
- 如果
a[i]等于b[j],说明找到了一个交集元素,将其加入结果列表,并同时移动两个指针。 - 如果
a[i]小于b[j],说明a[i]不可能在b中出现,移动i指针。 - 如果
a[i]大于b[j],说明b[j]不可能在a中出现,移动j指针。
- 如果
- 反转结果:由于题目要求结果按从大到小的顺序输出,因此在返回结果之前,需要将结果列表反转。
总结
通过双指针法,我们可以高效地找到两个有序数组的交集,并按要求输出结果。这个方法的时间复杂度为 O(n + m),空间复杂度为 O(min(n, m)),其中 n 和 m 分别是两个数组的长度。
代码
def solution(a, b):
# 初始化两个指针,指向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 # a中的元素小于b中的元素,移动a的指针
else:
j += 1 # b中的元素小于a中的元素,移动b的指针
# 将结果反转,按从大到小输出
return result[::-1]
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])
优化思路
-
减少不必要的反转操作:
- 当前代码在找到交集元素后,先将它们按从小到大的顺序存储在
result列表中,最后再反转结果。实际上,我们可以直接在找到交集元素时,将其插入到result列表的头部,这样就不需要最后再反转结果了。
- 当前代码在找到交集元素后,先将它们按从小到大的顺序存储在
-
减少不必要的比较:
- 在双指针遍历过程中,如果
a[i]和b[j]不相等,我们可以直接跳过一些不必要的比较。例如,如果a[i]小于b[j],我们可以直接将i移动到a中第一个大于等于b[j]的位置。
- 在双指针遍历过程中,如果