a = [2, 3, 3, 4, 4, 5]
b1 = [0, 2, 2, 3, 3, 4, 6, 8]
我们需要统计列表 a 中元素在列表 b1 中出现的次数,其中重复元素也需要计算在内。
2、解决方案
为了解决这个问题,我们可以使用多种方法。以下是一些常用的解决方案:
(1)使用集合交集运算
我们可以使用 Python 的 collections.Counter 类来计算两个列表的并集和交集。交集操作可以帮助我们快速找到两个列表中相同的元素,而并集操作可以帮助我们统计重复元素出现的次数。
import collections
def common_elements(list1, list2):
# 初始化两个 Counter 对象,分别统计列表1和列表2中元素出现的次数
counter1 = collections.Counter(list1)
counter2 = collections.Counter(list2)
# 计算并集
union = counter1 + counter2
# 计算交集
intersection = counter1 & counter2
# 统计交集中每个元素出现的次数
common_counts = [union[key] for key in intersection]
# 返回交集中所有元素出现的次数之和
return sum(common_counts)
(2)使用双指针法
双指针法是一种比较两个有序列表的常用算法。我们可以使用两个指针,分别指向两个列表的第一个元素。然后,我们可以同时遍历两个列表,比较两个指针指向的元素。如果两个元素相等,则将它们标记为相同元素,并分别将两个指针指向下一个元素。如果两个元素不相等,则将指针指向较小的元素。
def common_elements(list1, list2):
# 初始化两个指针,分别指向列表1和列表2的第一个元素
i = 0
j = 0
# 统计相同元素出现的次数
common_count = 0
# 循环遍历两个列表
while i < len(list1) and j < len(list2):
# 如果两个指针指向的元素相等
if list1[i] == list2[j]:
# 统计相同元素出现的次数
common_count += 1
# 将两个指针指向下一个元素
i += 1
j += 1
# 如果列表1的元素较大
elif list1[i] > list2[j]:
# 将指针j指向下一个元素
j += 1
# 如果列表2的元素较大
else:
# 将指针i指向下一个元素
i += 1
# 返回相同元素出现的次数
return common_count
(3)使用 Counter 类和排序后的列表
如果两个列表都经过排序,我们可以使用 collections.Counter 类来统计列表1中元素在列表2中出现的次数。具体步骤如下:
- 将列表2转换为
collections.Counter对象,以便快速查找元素出现的次数。 - 遍历列表1,对于每个元素,查找其在列表2中的出现次数,并将其添加到统计结果中。
import collections
def common_elements(list1, list2):
# 将列表2转换为 Counter 对象
counter = collections.Counter(list2)
# 统计列表1中元素在列表2中出现的次数
common_counts = [counter[element] for element in list1]
# 返回列表1中元素在列表2中出现的次数之和
return sum(common_counts)
(4)使用二分查找法
如果列表2非常长,我们可以使用二分查找法来快速查找列表1中元素在列表2中出现的次数。具体步骤如下:
- 对于列表1中的每个元素,使用二分查找法在列表2中查找其出现的位置。
- 如果找到该元素,则统计其出现的次数。
- 如果没有找到该元素,则将其标记为不存在。
def common_elements(list1, list2):
# 统计相同元素出现的次数
common_count = 0
# 对于列表1中的每个元素
for element in list1:
# 使用二分查找法在列表2中查找其出现的位置
index = binary_search(element, list2)
# 如果找到该元素
if index != -1:
# 统计相同元素出现的次数
common_count += 1
# 返回相同元素出现的次数
return common_count
def binary_search(element, list2):
# 设置左右边界
left = 0
right = len(list2) - 1
# 循环搜索
while left <= right:
# 计算中间位置
mid = (left + right) // 2
# 如果中间位置的元素等于要查找的元素
if list2[mid] == element:
# 返回中间位置
return mid
# 如果中间位置的元素大于要查找的元素
elif list2[mid] > element:
# 将右边界设置为中间位置的前一个位置
right = mid - 1
# 如果中间位置的元素小于要查找的元素
else:
# 将左边界设置为中间位置的后一个位置
left = mid + 1
# 如果没有找到该元素
return -1