[Leetcode学习-java]Smallest Integer Divisible by K

问题:

难度:medium

说明:

求一个数字 N,N 是由十进制的 1 组成(意思是 1, 11, 111, 1111 都是十进制的数字,不是二进制),然后 N 能够被 K 整除(被整除,就是 N % K  余数为 0),返回一个值最小的 N。

题目连接:https://leetcode.com/problems/smallest-integer-divisible-by-k/submissions/

输入案例:

Example 1:
Input: K = 1
Output: 1
Explanation: The smallest answer is N = 1, which has length 1.

Example 2:
Input: K = 2
Output: -1
Explanation: There is no such positive integer N divisible by 2.

Example 3:
Input: K = 3
Output: 3
Explanation: The smallest answer is N = 111, which has length 3.

我的代码:

其实题目很让人迷惑,说 N 由 1 组成,可能想不通究竟是什么 1,然后 N 被 K整除,意思是 N 除以 K 没有余数,而且 N 是 1, 11 ,111 这样的 十进制数字。

比较数学的题目,看了好久才明白过来,根据公式

mod( i ) = N ( i ) % K

mod( i + 1) = N( i + 1) % K

N( i + 1 ) = N( i ) * 10 + 1

因此得出:mod( i + 1 ) = ( mod( i ) * 10 + 1 ) % K,是分治法。

然后因为,如果是没有能被 K 整除的 N 的数字时候,mod( i ) 会出现一个循环的规则,是需要判断余数是否出现循环就行了,做个 map 缓存。

(不要往 for 循环乱丢东西啊!)

用 map 缓存

class Solution {
    private static boolean[] map = new boolean[50000];
    public int smallestRepunitDivByK(int K) {
        if((K & 1) != 0) {
            Arrays.fill(map, false);
            for(int mod = 1 % K, times = 1;!map[mod];map[mod] = true, mod = (mod * 10 + 1) % K, ++ times) 
                if(mod == 0) return times;
        }
        return -1;
    }
}

如果优化一下,就是当 times <= K 的时候都没办法得出 0 余数,那肯定也没救,因为 map[].length == K,如果已经是 K + 1 肯定是出现重复了。

class Solution {
    public int smallestRepunitDivByK(int K) {
        if((K & 1) != 0) 
            for(int mod = 1 % K, times = 1;times <= K;mod = (mod * 10 + 1) % K, ++ times) 
                if(mod == 0) return times;
        return -1;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_28033719/article/details/110188247
今日推荐