解题思路
本题目要求在给定的笔和本子之间,找到最多的匹配对数。匹配规则如下:
- 如果一支笔和一本本子的颜色相同,则它们可以匹配。
- 如果一支笔或一本本子的颜色为
-1
,则它可以与任意颜色匹配。
因此,我们的目标是尽可能多地找到满足匹配条件的笔和本子。
为了实现这个目标,可以按照以下步骤设计代码。
代码详解
我们使用如下代码来实现这个解法:
from collections import Counter
def solution(n: int, m: int, a: list, b: list) -> int:
count = 0
count_ = a.count(-1) # 统计彩色笔的数量
count_1 = b.count(-1) # 统计彩色本子的数量
# 构造 b 的计数器,避免多次 remove 操作
b_counter = Counter(b)
# 第一轮匹配:尝试让每支非彩色笔匹配到相同颜色的本子
for i in a:
if i != -1 and b_counter[i] > 0:
count += 1 # 匹配成功,增加匹配计数
b_counter[i] -= 1 # 将本子从计数中移除,避免重复使用
# 第二轮匹配:考虑彩色笔和彩色本子的匹配
# 可以利用彩色笔或彩色本子来进行额外的匹配
total_compatible = count + min(count_ + count_1, len(a) - count, len(b) - count)
return total_compatible
详细分析
-
统计彩色笔和彩色本子的数量:
- 由于彩色笔和彩色本子可以与任意颜色匹配,代码首先通过
count_ = a.count(-1)
和count_1 = b.count(-1)
来分别统计彩色笔和彩色本子的数量。 - 这些计数值将用于第二轮匹配。
- 由于彩色笔和彩色本子可以与任意颜色匹配,代码首先通过
-
创建颜色计数器:
- 使用
Counter
来统计每种颜色的本子数量。这种方法避免了后续的remove
操作,使得匹配过程更加高效。 Counter(b)
构造了一个字典,其中键为颜色,值为该颜色本子的数量。
- 使用
-
第一轮匹配:
- 第一轮匹配是尝试让每支非彩色笔优先匹配到相同颜色的本子:
- 遍历笔列表
a
,对每支非彩色笔i
检查是否有颜色匹配的本子(即b_counter[i] > 0
)。 - 如果匹配成功,则
count
增加1,且将b_counter[i]
减少1,以避免重复使用该本子。
- 遍历笔列表
- 第一轮匹配是尝试让每支非彩色笔优先匹配到相同颜色的本子:
-
第二轮匹配:
- 第一轮匹配结束后,剩余的未匹配的彩色笔和彩色本子可以用于额外的匹配:
count_ + count_1
是所有彩色笔和本子的数量,它们可以匹配剩下的未匹配的笔和本子。- 由于可能存在笔数或本子数不足以配对所有彩色笔或彩色本子,所以取三者之间的最小值
min(count_ + count_1, len(a) - count, len(b) - count)
。
- 最终匹配总数为
count + min(count_ + count_1, len(a) - count, len(b) - count)
。
- 第一轮匹配结束后,剩余的未匹配的彩色笔和彩色本子可以用于额外的匹配:
时间复杂度分析
- 统计彩色笔和本子的数量,时间复杂度为 (O(n + m))。
- 第一轮匹配中,遍历笔列表,时间复杂度为 (O(n))。
- 创建计数器的时间复杂度为 (O(m))。
总时间复杂度为 (O(n + m)),空间复杂度为 (O(m))(计数器的存储)。
总结
该解法有效地利用了计数器和条件匹配的逻辑,实现了笔与本子之间的最大匹配数量。