题干:给定正整数 k ,你需要找出可以被 k 整除的、仅包含数字 1 的最 小 正整数 n 的长度。
返回 n 的长度。如果不存在这样的 n ,就返回-1。
注意: n 不符合 64 位带符号整数。
1.审题:
最小正整数n仅包含数字1--->1,11,111,1111等等,但是不符合64位带符号整数
给定l,满足n取余k为0;
2.分析解题:
1)初步思路:while循环,从1,11,111往后直到n取余k为0.同时需要输出长度。
2)优化1:1,11,111等不可能和2,5为倍数的数整除。
优化2:1,11,111往后不符合64位符号整数。因此找数学规律。
当k为7时,1%7=0余1 11%7=1余4((1*10+1)%7=4) 111%7=15余6((4*10+1)%7=6)
所以不需要从1,11,111往后,可以采用上次的余数乘10加1也有同样的效果,具体为数学规律(自行推导)。
优化3:如果余数相同时,证明该k和n没有可以整除的数,余数会一直循环。因此采用STL中的unordered_set,此容器可以查找数据,将所有余数存入,存入前查找,发现能查找直接退出循环返回-1。
具体代码如下:
class Solution {
public:
int smallestRepunitDivByK(int k) {
//分析:只有k为1,3,7,9的时候有解;
//也就是2,4,5,6,8时无解(k属于0~9)时
int rem=1%k;
if(k%2==0||k%5==0){
return -1;
}
//当余数重复出现时,也证明此k无解
unordered_set<int> s;
s.insert(rem);
while(rem!=0){
//num = num*10+1;
rem=(rem*10+1)%k;
if(s.find(rem)!=s.end()){
return -1;
}
s.insert(rem);
}
return s.size();
}
};