1015. 可被 K 整除的最小整数
难度:中等
时间:2023/05/11
给定正整数 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 <= 10^5
思路与算法
从小到大遍历所有的可能的只包含1的数值,对于每一个数值,计算其关于k的余数。
如果余数为0,那么该数就是满足条件的最小数值,返回其长度即可。
如果余数不为0,则将该余数存入哈希表中,如果在之后的遍历中又出现该余数,说明遍历将跳入一个循环,不存在满足条件的数值,所以直接返回-1即可。
返回的n是1, 11, 111, 1111....如果开始时n=1,那么后续可以表示为n * 10 + 1,现在要求n % k == 0,那么就是相当于求(n * 10 +1 ) % k == 0,等价于 (n * 10 % k + 1) % k == 0,由此可知当且仅当k为2或者5时n%k永远等于1,其他情况下一定存在解。
直接x10+1必然会溢出,考虑到 (Ax10+1)%K = (A%K x10+1)%K,遂采用取余的方法来替代原数直接乘。 K为偶数或者末位为5的时候得不出1,遂剔除。
func smallestRepunitDivByK(k int) int {
if k%2 == 0 || k%5 == 0 {
return -1
}
cnt, cur := 1, 1
for {
if cur%k == 0 {
return cnt
}
cur = (cur*10 + 1) % k
cnt++
}
}
class Solution {
public int smallestRepunitDivByK(int K) {
if (K%2==0||K%5==0)return -1;
int remainder = 0;
int length = 1;
while (true){
remainder = (remainder*10+1)%K;
if (remainder==0)break;
length++;
}
return length;
}
}