力扣——1015. 可被 K 整除的最小整数

124 阅读2分钟

力扣——1015. 可被 K 整除的最小整数

1015. 可被 K 整除的最小整数

给定正整数 k ,你需要找出可以被 k 整除的、仅包含数字 **1** 的最 正整数 n 的长度。

返回 n 的长度。如果不存在这样的 n ,就返回-1。

注意: n 不符合 64 位带符号整数。

示例 1:

输入:k = 1
输出:1
解释:最小的答案是 n = 1,其长度为 1

示例 2:

输入:k = 2
输出:-1
解释:不存在可被 2 整除的正整数 n 。

示例 3:

输入:k = 3
输出:3
解释:最小的答案是 n = 111,其长度为 3

提示:

  • 1 <= k <= 105

问题解析

首先我们很容易想到,如果是偶数,或者是以5为结尾的数,他们的倍数尾部绝对不会有1,自然不会满足条件。所以如果给的数k是偶数或者是5的倍数,我们直接返回-1即可。

然后如果我们枚举1的位数,来进行计算,复杂度高不说,而且即便是longlong结构,也只有19位数,而本题的结果动辄几百上千位数,所以这个做法显然是不行的。

这里要用到我们小学中就学到的竖式除法。

先用一个数做被除数num,逐步增加1的位数知道大于等于k为止。然后开始除,如果除完之后被除数num为0,则当前的位数就是答案。

如果num不为0,则我们给他后面加上一个1,然后继续用k除。

重复如上步骤,直到num为0为止。

在此过程中记录添加的1的位数,最后返回位数就是此题的答案。

AC代码

class Solution {
public:
    int smallestRepunitDivByK(int k) {
        if(k%2==0||k%5==0)return -1;
        int num = 1, cnt = 1;
        while (num < k)
        {
            num *= 10;
            num += 1;
            cnt++;
        }
        while (num)
        {
            cout << num / k;
            num %= k;
            if (num == 0)break;
            cnt++;
            num *= 10 ;
            num++;
        }
        return cnt;
    }
};