此题解采用模拟方法以寻找由数字1组成的可以被k整除的最小正整数n。首先,对于任何由1组成的整数n,可以表示为如111...1(n个1),也可以表示为数字序列。该算法通过计算模k的余数来避免处理过大的整数。如果k为1,直接返回1因为1可以被1整除。如果k是2或5的倍数,那么不可能存在全1的数字能被k整除,因此返回-1。接着,使用一个集合来存储出现过的余数,从而检测循环。从1开始,逐步增加1的个数,计算每次形成的数模k的余数。如果余数为0,则当前的数就是答案。如果余数已经在集合中出现过,说明开始循环,不存在答案,返回-1。
时间复杂度: O(k)
空间复杂度: O(k)
from itertools import count
class Solution:
def smallestRepunitDivByK(self, k: int) -> int:
if k == 1:
return 1
if k % 2 == 0 or k % 5 == 0: # 2和5的倍数不可能有解
return -1
vis = set()
sz = 1 # 初始化长度为1
mod = 1 # 初始模为1
vis.add(mod)
for _ in count(2): # 从2开始无限计数
sz += 1
mod = (mod * 10 + 1) % k # 生成新的数并取模
if mod == 0:
return sz # 如果模为0,找到答案
if mod in vis:
return -1 # 如果模已经出现过,说明进入循环
vis.add(mod)