问题描述
小M和小F在玩飞行棋。游戏结束后,他们需要 将桌上的飞行棋棋子分组整理好。现在有N个 棋子,每个棋子上有一个数字序号。小M的目 标是将这些棋子分成M组,每组恰好5个,并且 组内棋子的序号相同。小M希望知道是否可以 按照这种方式对棋子进行分组。 例如,假设棋子序号为[1,2,3,4,5],虽 然只有5个棋子,但由于序号不同,因此不能形 成有效的分组。如果序号是[1,1,1,1,1 2,2,2,2,2],则可以形成两个有效分组: 因此输出为 True.
测试样例
样例1:
输入:nums =[1,2,3,4,5]
输出:"False'
样例2:
输入:nums =[1,1,1,1,2,1,2, 2,2,2]
输出:"True”
样例3:
输入:nums=[5,5,5,5,5,5,5, 5,5,5]
输出:"True"
解题思路
题目要求判断一个数组中是否每个元素的出现次数都是5的倍数。我们可以借助Python的 Counter 类来统计每个元素的出现次数,然后检查每个元素的计数是否都能被5整除。
代码
from typing import Counter
def solution(nums):
count = Counter(nums)
for key in count:
if count[key] % 5 != 0:
return "False"
return "True"
if __name__ == "__main__":
# You can add more test cases here
print(solution([1, 3, 4, 5, 6, 5, 4]) == "False" )
print(solution([1, 1, 1, 1, 2, 1, 2, 2, 2, 2]) == "True")
print(solution([11, 45, 49, 37, 45, 38, 3, 47, 35, 49, 26, 16, 24, 4, 45, 39, 28, 26, 14, 22, 4, 49, 18, 4, 4, 26, 47, 14, 1, 21, 9, 26, 17, 12, 44, 28, 24, 24, 10, 31, 33, 32, 23, 41, 41, 19, 17, 24, 28, 46, 28, 4, 18, 23, 48, 45, 7, 21, 12, 40, 2, 19, 19, 28, 32, 6, 27, 43, 6, 18, 8, 27, 9, 6, 6, 31, 37, 15, 26, 20, 43, 3, 14, 40, 20]
) == "False")
关键代码解释
Counter 会返回一个字典,其中键是数组中的唯一元素,值是该元素在数组中的出现次数。例如,Counter([1, 1, 1, 2, 2, 2]) 会返回 {1: 3, 2: 3}。
for循环里,遍历每个元素的计数,如果发现某个计数不是5的倍数,则立即返回 "False"。如果遍历结束都符合条件,则返回 "True"。
时间和空间复杂度分析
- 时间复杂度:
O(n),其中n是数组的长度。统计每个元素的频次需要O(n)时间,然后遍历所有唯一元素的频次需要O(m),其中m是数组中唯一元素的数量。总体时间复杂度为O(n + m),最坏情况下接近O(n)。 - 空间复杂度:
O(m),其中m是数组中唯一元素的数量。Counter类会存储每个唯一元素及其出现次数,因此空间复杂度取决于唯一元素的数量。
学习思路
在 Python 中,Counter 是 collections 模块中的一个类,用于快速计数和管理元素的出现频次。它可以统计可迭代对象(如字符串、列表、元组等)中每个元素的出现次数,并返回一个类似字典的对象,键是元素,值是它的出现次数。
此题运用Counter是很好的一个选择,它自动就帮我们把每个元素出现的次数统计好了,我们只需要遍历它返回的字典即可,但是这个用法是Python里的,其他语言不支持这种方法。
1. 引入和基础使用
首先需要从 collections 模块引入 Counter:
from collections import Counter
基本使用示例
假设我们想统计字符串 'aabbbcc' 中每个字符的出现次数,可以这样使用 Counter:
counter = Counter('aabbbcc')
print(counter)
# 输出: Counter({'b': 3, 'a': 2, 'c': 2})
在这个例子中,Counter 返回一个类似字典的对象,其中键是字符,值是每个字符的出现次数。
2. 常用方法和操作
初始化
Counter 可以接收不同的输入类型进行初始化:
- 字符串:按字符统计
- 列表或元组:按元素统计
- 字典:直接将字典的键值对视为元素及其频次
# 使用字符串初始化
counter1 = Counter('hello')
print(counter1) # Counter({'l': 2, 'h': 1, 'e': 1, 'o': 1})
# 使用列表初始化
counter2 = Counter([1, 2, 2, 3, 1, 3, 3])
print(counter2) # Counter({3: 3, 1: 2, 2: 2})
# 使用字典初始化
counter3 = Counter({'a': 2, 'b': 3})
print(counter3) # Counter({'b': 3, 'a': 2})
访问元素频次
类似字典,访问某个元素的频次可以通过键进行查询:
print(counter1['l']) # 输出: 2
若查询一个未出现的元素,返回 0 而不是报错:
print(counter1['x']) # 输出: 0
更新计数
使用 update 方法增加已有计数或加入新元素:
counter1.update('hello')
print(counter1) # Counter({'l': 4, 'h': 2, 'e': 2, 'o': 2})
减少计数
可以用 subtract 方法减少指定元素的计数:
counter1.subtract('he')
print(counter1) # Counter({'l': 4, 'o': 2, 'h': 1, 'e': 1})
查找最常见的元素
Counter.most_common() 返回一个按频次降序排列的元素列表,方便找到最常见的元素:
print(counter1.most_common(2)) # [('l', 4), ('o', 2)]
删除或清空计数
使用 del 可以删除某个元素,clear 则可以清空所有计数:
del counter1['h']
print(counter1) # Counter({'l': 4, 'o': 2, 'e': 1})
counter1.clear()
print(counter1) # Counter()
总结
Counter 是一个方便的计数工具,适合处理简单的计数统计需求。