Medium
题目描述
给定正整数 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
提示:
- 11111 = 1111 * 10 + 1
- 我们只需要存储模 K 的余数。
- 如果我们从未得到余数 0,为什么会发生这种情况,我们如何知道?
解题思路
这道题要求找到只包含数字1且能被k整除的最小正整数的长度。
核心思路: 我们可以构造形如1、11、111、1111…的数列,逐步检查是否能被k整除。关键观察是:
- 1 % k
- 11 % k = (1 * 10 + 1) % k = ((1 % k) * 10 + 1) % k
- 111 % k = (11 * 10 + 1) % k = ((11 % k) * 10 + 1) % k
算法步骤:
- 如果k能被2或5整除(除了k=5的特殊情况),那么不存在解,因为只含1的数不可能被2或5整除
- 从余数1开始,每次计算
remainder = (remainder * 10 + 1) % k - 如果余数变为0,说明找到了答案
- 如果余数重复出现,说明进入循环,不存在解
优化分析:
- 使用哈希集合记录出现过的余数,避免无限循环
- 根据鸽笼原理,最多k-1个不同的非零余数,所以最多迭代k次
时间复杂度: O(k)
空间复杂度: O(k)
代码实现
class Solution {
public:
int smallestRepunitDivByK(int k) {
if (k % 2 == 0 || k % 5 == 0) {
return -1;
}
unordered_set<int> seen;
int remainder = 1;
int length = 1;
while (remainder % k != 0) {
if (seen.count(remainder)) {
return -1;
}
seen.insert(remainder);
remainder = (remainder * 10 + 1) % k;
length++;
}
return length;
}
};
class Solution:
def smallestRepunitDivByK(self, k: int) -> int:
if k % 2 == 0 or k % 5 == 0:
return -1
seen = set()
remainder = 1
length = 1
while remainder % k != 0:
if remainder in seen:
return -1
seen.add(remainder)
remainder = (remainder * 10 + 1) % k
length += 1
return length
public class Solution {
public int SmallestRepunitDivByK(int k) {
if (k % 2 == 0 || k % 5 == 0) {
return -1;
}
HashSet<int> seen = new HashSet<int>();
int remainder = 1;
int length = 1;
while (remainder % k != 0) {
if (seen.Contains(remainder)) {
return -1;
}
seen.Add(remainder);
remainder = (remainder * 10 + 1) % k;
length++;
}
return length;
}
}
var smallestRepunitDivByK = function(k) {
if (k % 2 === 0 || k % 5 === 0) return -1;
let remainder = 0;
for (let length = 1; length <= k; length++) {
remainder = (remainder * 10 + 1) % k;
if (remainder === 0) return length;
}
return -1;
};
复杂度分析
| 复杂度类型 | 分析 |
|---|---|
| 时间复杂度 | O(k) - 最多迭代k次,每次操作为常数时间 |
| 空间复杂度 | O(k) - 哈希集合最多存储k-1个余数 |