一、Problem
给定正整数 K,你需要找出可以被 K 整除的、仅包含数字 1 的最小正整数 N。
返回 N 的长度。如果不存在这样的 N,就返回 -1。
示例 1:
输入:1
输出:1
解释:最小的答案是 N = 1,其长度为 1。
输入:2
输出:-1
解释:不存在可被 2 整除的正整数 N 。
提示:
1 <= K <= 10^5
二、Solution
方法一:set 判重
思路
只包含 1 的数字的推导方法是:N = N × 10 + 1(N 初值为 1)
,但为防止溢出,我们在外面增加了一层取模:N = (N × 10 + 1) % K)
如果求解 N的过程中,遇到了重复数字,那么证明该数字永远不能被 K 整除了,返回 -1 即可
特判:当 N 为 1 且 K 为 1 时,N 可被 K 整除,应立即返回 1
class Solution {
public int smallestRepunitDivByK(int K) {
int N = 1 % K, len = 1;
Set<Integer> seen = new HashSet<>();
while (N != 0) {
if (seen.contains(N))
return -1;
seen.add(N);
N = (N * 10 + 1) % K;
len++;
}
return len;
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,
方法二:数学推导 = 空间压缩
别人的给出的证明说 K = 2 或 5 的倍数时,全 1 数字不可能被此时的 K 除尽,其它一样…
class Solution {
public int smallestRepunitDivByK(int K) {
if (K % 2 == 0 || K % 5 == 0)
return -1;
int N = 1, len = 1;
while (N % K != 0) {
N = (N * 10 + 1) % K;
len++;
}
return len;
}
}
复杂度分析
- 时间复杂度:,
- 空间复杂度:,