Skip to content

Files

Latest commit

c29b144 · May 17, 2024

History

History
157 lines (118 loc) · 3.62 KB

File metadata and controls

157 lines (118 loc) · 3.62 KB
comments difficulty edit_url rating source tags
true
中等
1874
第 129 场周赛 Q2
哈希表
数学

English Version

题目描述

给定正整数 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

解法

方法一:数学

我们注意到,正整数 n 初始值为 1 ,每次乘以 10 后再加 1 ,即 n = n × 10 + 1 ,而 ( n × 10 + 1 ) mod k = ( ( n mod k ) × 10 + 1 ) mod k ,因此我们可以通过计算 n mod k 来判断 n 是否能被 k 整除。

我们从 n = 1 开始,每次计算 n mod k ,直到 n mod k = 0 ,此时 n 就是我们要求的最小正整数,其长度即为 n 的位数。否则,我们更新 n = ( n × 10 + 1 ) mod k 。如果循环 k 次后,仍然没有找到 n mod k = 0 ,则说明不存在这样的 n ,返回 1

时间复杂度 O ( k ) ,空间复杂度 O ( 1 ) 。其中 k 为给定的正整数。

Python3

class Solution:
    def smallestRepunitDivByK(self, k: int) -> int:
        n = 1 % k
        for i in range(1, k + 1):
            if n == 0:
                return i
            n = (n * 10 + 1) % k
        return -1

Java

class Solution {
    public int smallestRepunitDivByK(int k) {
        int n = 1 % k;
        for (int i = 1; i <= k; ++i) {
            if (n == 0) {
                return i;
            }
            n = (n * 10 + 1) % k;
        }
        return -1;
    }
}

C++

class Solution {
public:
    int smallestRepunitDivByK(int k) {
        int n = 1 % k;
        for (int i = 1; i <= k; ++i) {
            if (n == 0) {
                return i;
            }
            n = (n * 10 + 1) % k;
        }
        return -1;
    }
};

Go

func smallestRepunitDivByK(k int) int {
	n := 1 % k
	for i := 1; i <= k; i++ {
		if n == 0 {
			return i
		}
		n = (n*10 + 1) % k
	}
	return -1
}

TypeScript

function smallestRepunitDivByK(k: number): number {
    let n = 1 % k;
    for (let i = 1; i <= k; ++i) {
        if (n === 0) {
            return i;
        }
        n = (n * 10 + 1) % k;
    }
    return -1;
}