题面
小M和小F在玩飞行棋。游戏结束后,他们需要将桌上的飞行棋棋子分组整理好。现在有 N 个棋子,每个棋子上有一个数字序号。小M的目标是将这些棋子分成 M 组,每组恰好5个,并且组内棋子的序号相同。小M希望知道是否可以按照这种方式对棋子进行分组。
例如,假设棋子序号为 [1, 2, 3, 4, 5],虽然只有5个棋子,但由于序号不同,因此不能形成有效的分组。如果序号是 [1, 1, 1, 1, 1, 2, 2, 2, 2, 2],则可以形成两个有效分组,因此输出为 True。
问题分析
小M希望将 N 个棋子分成 M 组,每组恰好 5 个棋子,并且每组中的棋子的序号相同。我们的任务是判断是否能按照这种方式进行分组。
要做到这一点,我们需要:
- 每组有 5 个相同序号的棋子:这意味着棋子序号的出现频次必须是 5 的倍数。
- 总共有 M 组:可以通过统计每个棋子的频次来判断能否形成 M 组。
解题思路
- 统计棋子序号的频次:我们首先统计所有棋子序号的出现次数。
- 检查每个频次是否为 5 的倍数:每个序号的棋子数量必须是 5 的倍数。如果有任何一个序号的频次不能被 5 整除,则返回
False。 - 计算分组数量:通过将每个序号的频次除以 5,我们得到每个序号可以组成的组数。如果所有序号的组数之和等于 M,则返回
True,否则返回False。
解题步骤
- 使用
Counter来统计每个棋子序号的频次。 - 遍历每个棋子序号,检查其频次是否为 5 的倍数,并计算能组成的组数。
- 如果总组数等于 M,则输出
True,否则输出False。
代码实现
from collections import Counter
def canDivideIntoGroups(chess_pieces, M):
# 统计每个棋子序号的频次
freq = Counter(chess_pieces)
# 计算总共能组成的组数
total_groups = 0
# 遍历每个棋子的序号和频次
for count in freq.values():
# 如果某个频次不能被 5 整除,则无法分组
if count % 5 != 0:
return False
# 计算当前序号可以组成的组数
total_groups += count // 5
# 检查是否能组成 M 组
return total_groups == M
# 测试案例
chess_pieces1 = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2]
M1 = 2
print(canDivideIntoGroups(chess_pieces1, M1)) # 输出: True
chess_pieces2 = [1, 2, 3, 4, 5]
M2 = 1
print(canDivideIntoGroups(chess_pieces2, M2)) # 输出: False
代码解释
-
Counter(chess_pieces):通过Counter对chess_pieces中的每个棋子序号进行计数,得到一个字典,键是棋子序号,值是该序号出现的次数。 -
遍历频次:通过
for count in freq.values()遍历每个棋子序号的出现频次,检查是否能够分组。- 如果某个序号的频次不能被 5 整除,直接返回
False。 - 如果能被 5 整除,则将频次除以 5,得到该序号可以组成的组数。
- 如果某个序号的频次不能被 5 整除,直接返回
-
总组数检查:将所有序号组成的组数加起来,判断是否等于 M。如果相等,则返回
True,否则返回False。
复杂度分析
- 时间复杂度:O(N),其中 N 是棋子的数量。我们需要对棋子序号进行一次遍历,统计其频次,然后再遍历频次进行判断。
- 空间复杂度:O(K),其中 K 是不同棋子序号的数量。我们使用
Counter存储每个序号的频次,空间复杂度与不同序号的数量成正比。
测试案例
-
测试用例 1:
chess_pieces = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2] M = 2 print(canDivideIntoGroups(chess_pieces, M)) # 输出: True- 解释:可以将序号 1 和 2 的棋子分别分成两组,每组 5 个。
-
测试用例 2:
chess_pieces = [1, 2, 3, 4, 5] M = 1 print(canDivideIntoGroups(chess_pieces, M)) # 输出: False- 解释:虽然有 5 个棋子,但它们的序号不同,无法组成一组。
-
测试用例 3:
chess_pieces = [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2] M = 2 print(canDivideIntoGroups(chess_pieces, M)) # 输出: False- 解释:序号 1 有 7 个棋子,无法组成一个完整的组,因此无法组成有效的分组。
总结
通过统计棋子的频次并验证每个频次是否是 5 的倍数,我们可以高效地判断是否可以将棋子分成指定数量的组。