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

140 阅读1分钟

从零开始学习c++,每天起码做一道leetcode题目,在此记录,希望最后能够有所收获!

一、题目描述

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

二、思路分析

本题不能直接列举n, n 只能由 1 组成,虽然可以通过公式 n = n * 10 + 1 不断地得到下一个 n ,直至 n 对 k 取余 为 0,最后返回 n 的长度即可,然而单纯的使用这种暴力破解的方法,n 会变得相当大,计算异常耗时,最终导致时间超时,因此需要考虑从 余数 入手,因为 余数 永远不会大于 k !

这就涉及到了两个关于取模的公式:

image.png

根据这两个公式,可以对通用的公式n(m)=n(m-1)*10+1进行推导,依此我们就可以得到余数r间的关系:

image.png

同时可以优化一下,k若为偶数,则k的倍数必为偶数,个位数上不可能为1;同样的k若为5的倍数,则个位数上不是0就是5,不可能是1

三、AC代码

class Solution {
public:
    int smallestRepunitDivByK(int k) {
        int ans=1;
        int t=ans%k;
        unordered_set<int>record;
        while(t!=0){
            t=(t*10+1)%k;
            if(!record.count(t)){
                record.insert(t);             
            }
            else{
                break;               
            }           
        }
        if(t==0){
            
            return record.size()+1;
        }        
            return -1;
    }
};

四、总结

主要需要知道取余的那两条规则。