【算法】Smallest Integer Divisible by K 可被 K 整除的最小整数

news/2024/7/8 4:35:45

文章目录

  • Smallest Integer Divisible by K 可被 K 整除的最小整数
    • 问题描述:
    • 分析
    • 代码
  • Tag

Smallest Integer Divisible by K 可被 K 整除的最小整数

问题描述:

问题
给定正整数 k ,你需要找出可以被 k 整除的、仅包含数字 1 的【最小正整数】 n 的长度。

返回 n 的长度。如果不存在这样的 n ,就返回-1。

注意: n 不符合 64 位带符号整数。

分析

就是寻找一个 n,这个n需要满足几个条件
1 n是一个整数
2 n%k == 0
3 n 的数位只包含 1
暴力的思路就是枚举所有的可能n,即 1,11,111,1111,1…1.
然后对于每个数进行条件123的检测。因为在这个过程中,每个枚举的数都是位数逐渐增加的,所以只要找到第一个就可以。
整体思路很OK,然而怎么可能那么简单。只能说上面的思路对,又不完全的对。
如果存在一种k,任何一个枚举的n都不能满足n%k==0,那么上面的思路,不停的扩展枚举数的位数,就是无意义的,而且无法退出,因为永远都无法找到这样的n。
此外,问题中还提示,n 不符合64位有符合整数。原文是n may not fit in a 64-bit signed integer.
这意思就是说,可能n比2^64还大,这样的数以目前的int,long都无法处理。
所以新的问题就是 对于k来说,是否存在符合上面条件的n。对于k=2,很明显2的倍数尾数必然是偶数24680,所以绝对不可能有这样的n,可以返回-1.
类似的还有5,其倍数也是05结尾。
回到之前的暴力,当n=1,长度为1,如果 n mod k = remainder1 =0,那么结果就是1.如果 remainder1!=0,那么就需要扩展得到n’= 10n +1,即11 ,11 mod k = remainder2.如果 remainder2=0,也可以说明结果是2,否则就需要继续扩展。
这里有个mod,就是模计算,求余用的。你会不会想到些什么。
(a+b)%m = (a%m+b%m)%m
(ab)%m = ((a%m)(b%m))%m
对于 11 mod k ==> (10+1)mod k,
即 n’ mod k ==>(10n +1 ) mod k
==> [(10n) mod k + (1 mod k) ] mod k
==> [ (10 mod k)*( n mod k ) + (1 mod k)] mod k

==> [ (10 mod k)*remainderOld + (1 mod k)] mod k
==> [ (10 mod k)(remainderOld mod k) + (1 mod k)] mod k
==> [ (10
remainderOld mod k) + 1] mod k
==> [ (10*remainderOld) + 1] mod k
== remainderNew
= = > [ ( 10 n ) m o d k + ( 1 m o d k ) ] m o d k = = > [ ( 10 m o d k ) ∗ ( n m o d k ) + ( 1 m o d k ) ] m o d k ==> [(10n) mod k + (1 mod k) ] mod k ==> [ (10 mod k)*( n mod k ) + (1 mod k)] mod k ==>[(10n)modk+(1modk)]modk==>[(10modk)(nmodk)+(1modk)]modk

= = > [ ( 10 m o d k ) ∗ r e m a i n d e r O l d + ( 1 m o d k ) ] m o d k = = > [ ( 10 m o d k ) ∗ ( r e m a i n d e r O l d m o d k ) + ( 1 m o d k ) ] m o d k ==> [ (10 mod k)*remainderOld + (1 mod k)] mod k ==> [ (10 mod k)*(remainderOld mod k) + (1 mod k)] mod k ==>[(10modk)remainderOld+(1modk)]modk==>[(10modk)(remainderOldmodk)+(1modk)]modk

= = > [ ( 10 ∗ r e m a i n d e r O l d m o d k ) + 1 ] m o d k = = > [ ( 10 ∗ r e m a i n d e r O l d ) + 1 ] m o d k = = r e m a i n d e r N e w ==> [ (10*remainderOld mod k) + 1] mod k ==> [ (10*remainderOld) + 1] mod k == remainderNew ==>[(10remainderOldmodk)+1]modk==>[(10remainderOld)+1]modk==remainderNew

到此,前一个n和后一个n 关于k就有一个关系。
这样每一次都可以通过前一个remainder,计算得到当前n’的remainder。remainder有什么用,你品。
remainder的范围就是[0,k-1],所以使用set记录,当set出现重复的remainder,就说明继续计算也无法得到新的remainder,可以结束,返回-1.

时间复杂度 O(k)
空间复杂度: O(k)

代码

class Solution {
    public int smallestRepunitDivByK(int k) {
        int resid = 1 % k, len = 1; // resid为余数,len为数字长度,初始值为1
        Set<Integer> set = new HashSet<Integer>(); // 创建一个无序集合,用于存储余数
        set.add(resid); // 插入余数1
        while (resid != 0) { // 当余数为0时退出循环
            resid = (resid * 10 + 1) % k; // 计算下一个余数
            len++; // 数字长度+1
            if (set.contains(resid)) { // 如果余数重复出现,则无解
                return -1;
            }
            set.add(resid); // 将余数插入集合
        }
        return len; // 返回数字长度 
    }
} 

Tag

哈希 数论


http://lihuaxi.xjx100.cn/news/1117199.html

相关文章

杂记 2023.5.10

目录 韦伯和斯托亚科维奇是谁&#xff1f; 介绍一下kali FastDFS和Sentinel是什么&#xff1f; Inferno 找工作的影响因素 1. 背景&#xff1a; 2. 学习过程&#xff1a; 2.1 计算机基础&#xff1a; 2.2 语言&#xff1a; 2.3 数据库等&#xff1a; 2.4 JVM&#…

CCFCSP 201409-2 画图

思路上很容易想到即使用一个标记数组对上过色的模块进行标记&#xff0c;最后遍历该数组得到被标记的模块数即可 #include<iostream>using namespace std;int mapp[105][105]; int ans0;int main(){int n;cin>>n;for(int i0;i<n;i){int x1,y1,x2,y2;cin>>…

JavaScript经典教程(七)-- JavaScript初级

190&#xff1a;JavaScript初级内容 - DOM查询、插入内容、赋予样式等 1、DOM操作 DOM&#xff1a;节点&#xff0c;也就是html中的元素&#xff1b; DOM操作&#xff1a;其实就是节点元素的方法&#xff1b; &#xff08;1&#xff09;innerHTML - 返回元素内容 同时也可以…

表达式求值问题-双栈模板化实现

好久不见&#xff0c;真的很久都没有更新博客了&#xff0c;最近很多事情&#xff0c;所以比较忙碌&#xff0c;没有时间每天都学算法&#xff0c;但是我会挤时间尽量做到&#xff0c;每两三天就更新博客&#xff0c;我会努力的&#xff0c;加油~ 前言&#xff1a;计算器都见过…

SpringBoot基础篇1(搭建环境+基础配置)

一、SpingBoot入门案例 SpringBoot是用来简化Spring应用的初始搭建以及开发过程。 先快速搭建一个SpringBoot&#xff1a; 创建一个空project&#xff0c;再创建SpringBoot模块。 点击Create&#xff0c;出现以下页面配置成功 创建一个控制器测试一下&#xff1a; RestCo…

SeaweedFS学习笔记:调优

文章目录 1. 使用 LevelDB 作为索引的存储2. 预先分配volume file的磁盘空间3. 提高写并发4. 提供读并发5. 增加更多的硬盘驱动器6. 提高用户打开文件的限制数7. 内存消耗7.1 内存中的索引7.2 并发读 8. 当网络不稳定时 1. 使用 LevelDB 作为索引的存储 在启动Volume server时…

AI 不会取代打工人,使用 AI 的人才会

一、被AI端掉饭碗之前&#xff0c;提升自己的硬核实力 AI工具带来了工业革命级别的效率提升&#xff0c;除了强大&#xff0c;更多的引发了打工人的集体焦虑&#xff1a;“我的活ai都能干了&#xff0c;那我做什么呢&#xff1f;” 当然&#xff0c;还有另一种更积极的解答&a…