Leetcode 3790. Smallest All-Ones Multiple

1. 解题思路

这一题是leetcode周赛482的第三题,是一道medium的题目。

这一题的解法并不难,主要是数学证明的思路还是挺有意思的,是一个典型的数论问题的处理方法。

这一题的核心在于发现:

  • 如果 k k k不为 2 2 2 5 5 5的倍数,那么在 1 , 11 , ⋯   , 11 ⋯ 1 1,11,\cdots,11\cdots1 1,11,,111当中,必然存在某一个数恰好为 k k k的倍数,且长度不超过 k k k

其中, 2 2 2 5 5 5的倍数不满足题意这一点是可以直接看出来的,剩下的就是证明其余的数都可以找到一个长度不超过 k k k位的数。

我们是用反证法,假设不存在这么一个数,那么我们取 1 1 1 1 ⋯ 1 1\cdots1 11 k k k个数,其关于 k k k的余数至少有两个数是相同的,然后我们将其相减,则必然得到一个数 1 ⋯ 10 ⋯ 0 1\cdots10\cdots0 1100恰好为 k k k的倍数,而这个数又可以写为 1 ⋯ 1 × 10 m 1\cdots1 \times 10^m 11×10m,显然 10 m 10^m 10m k k k互质,因此,其前缀 1 ⋯ 1 1\cdots1 11必然可以被 k k k整除,且其长度不超过 k k k,与假设矛盾。

因此,我们只需要一个循环,即可在至多 k k k次查找中找到目标的数。

2. 代码实现

给出python代码实现如下:

class Solution:
    def minAllOneMultiple(self, k: int) -> int:
        if k % 2 == 0:
            return -1
        elif k % 5 == 0:
            return -1
        n, num = 1, 1
        while num % k != 0:
            num = (num * 10 + 1) % k
            n += 1
        return n

提交代码评测得到:耗时119ms,占用内存17.24MB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值