题目描述

求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。

思路

像类似这样的问题,我们可以通过归纳总结来获取相关的东西。

首先可以先分类:

个位
我们知道在个位数上,1会每隔10出现一次,例如1、11、21等等,我们发现以10为一个阶梯的话,每一个完整的阶梯里面都有一个1,例如数字22,按照10为间隔来分三个阶梯,在完整阶梯0-9,10-19之中都有一个1,但是19之后有一个不完整的阶梯,我们需要去判断这个阶梯中会不会出现1,易推断知,如果最后这个露出来的部分小于1,则不可能出现1(这个归纳换做其它数字也成立)。

我们可以归纳个位上1出现的个数为:

n/10 * 1+(n%10!=0 ? 1 : 0)

十位
现在说十位数,十位数上出现1的情况应该是10-19,依然沿用分析个位数时候的阶梯理论,我们知道10-19这组数,每隔100出现一次,这次我们的阶梯是100,例如数字317,分析有阶梯0-99,100-199,200-299三段完整阶梯,每一段阶梯里面都会出现10次1(从10-19),最后分析露出来的那段不完整的阶梯。我们考虑如果露出来的数大于19,那么直接算10个1就行了,因为10-19肯定会出现;如果小于10,那么肯定不会出现十位数的1;如果在10-19之间的,我们计算结果应该是k - 10 + 1。例如我们分析300-317,17个数字,1出现的个数应该是17-10+1=8个。

那么现在可以归纳:十位上1出现的个数为:

设k = n % 100,即为不完整阶梯段的数字
归纳式为:(n / 100) * 10 + (if(k > 19) 10 else if(k < 10) 0 else k - 10 + 1)
百位
现在说百位1,我们知道在百位,100-199都会出现百位1,一共出现100次,阶梯间隔为1000,100-199这组数,每隔1000就会出现一次。这次假设我们的数为2139。跟上述思想一致,先算阶梯数 * 完整阶梯中1在百位出现的个数,即n/1000 * 100得到前两个阶梯中1的个数,那么再算漏出来的部分139,沿用上述思想,不完整阶梯数k199,得到100个百位1,100<=k<=199则得到k - 100 + 1个百位1。

那么继续归纳百位上出现1的个数:

设k = n % 1000
归纳式为:(n / 1000) * 100 + (if(k >199) 100 else if(k < 100) 0 else k - 100 + 1)
后面的依次类推....

再次回顾个位
我们把个位数上算1的个数的式子也纳入归纳式中

k = n % 10
个位数上1的个数为:n / 10 * 1 + (if(k > 1) 1 else if(k < 1) 0 else k - 1 + 1)
完美!归纳式看起来已经很规整了。 来一个更抽象的归纳,设i为计算1所在的位数,i=1表示计算个位数的1的个数,10表示计算十位数的1的个数等等。

k = n % (i * 10)
count(i) = (n / (i * 10)) * i + (if(k > i * 2 - 1) i else if(k < i) 0 else k - i + 1)
好了,这样从10到10的n次方的归纳就完成了。

牛客网链接

js代码

function NumberOf1Between1AndN_Solution(n)
{
// write code here
if (n <= 0) return 0
let mod
let res = 0
for (let i = 1; i <= n; i *= 10) {
res += Math.floor(n / (i*10)) * i
mod = n % (i*10)
if (mod > i * 2 -1) res += i
else if (mod >= i && mod <= i * 2 -1 ) res += (mod - i + 1)
}
return res
}```

用js刷剑指offer(从1到n整数中1出现的次数)的更多相关文章

  1. 剑指 Offer 43. 1~n 整数中 1 出现的次数 + 数位模拟 + 思维

    剑指 Offer 43. 1-n 整数中 1 出现的次数 Offer_43 题目描述 题解分析 java代码 package com.walegarrett.offer; /** * @Author ...

  2. 每日一题 - 剑指 Offer 43. 1~n整数中1出现的次数

    题目信息 时间: 2019-07-01 题目链接:Leetcode tag: 整除 取余 规律 递归 难易程度:中等 题目描述: 输入一个整数 n ,求1-n这n个整数的十进制表示中1出现的次数. 例 ...

  3. 剑指 Offer 43. 1~n整数中1出现的次数

    题目描述 输入一个整数 n ,求1-n这n个整数的十进制表示中1出现的次数. 例如,输入12,1-12这些整数中包含1 的数字有1.10.11和12,1一共出现了5次. 示例 1: 输入:n = 12 ...

  4. 用js刷剑指offer(两个链表的第一个公共结点)

    题目描述 输入两个链表,找出它们的第一个公共结点. 牛客网链接 js代码 /*function ListNode(x){ this.val = x; this.next = null; }*/ fun ...

  5. 用js刷剑指offer(数组中的逆序对)

    题目描述 题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P ...

  6. 用js刷剑指offer(第一个只出现一次的字符)

    题目描述 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). 牛客网链接 js代码 fu ...

  7. 用js刷剑指offer(丑数)

    题目描述 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 思路 ...

  8. 用js刷剑指offer(把数组排成最小的数)

    题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路 对ve ...

  9. 用js刷剑指offer(连续子数组的最大和)

    题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...

随机推荐

  1. Xcode UI界面调试神器-injectionIII

    App Store搜索injectionIII下载即可,免费的哟. 打开injectionIII,运行即可. - (BOOL)application:(UIApplication *)applicat ...

  2. [LeetCode] 157. Read N Characters Given Read4 用Read4来读取N个字符

    The API: int read4(char *buf) reads 4 characters at a time from a file.The return value is the actua ...

  3. Java语言和JVM的使用说明书

    Java Language and Virtual Machine Specifications 详细介绍了Java语言各个版本的功能/JVM的工作原理 建议详读/深度 各个版本,在线看或者pdf下载

  4. QT--学习疑惑探索

    用C++定义了一个类,并注册到qml文件中,但是这个类只能用Quickview进行显示,用其他方法好像不行. 启发: 1  window控件类是没有parent的widget. 2 m_view = ...

  5. Linux thread process and kernel mode and user mode page table

    Linux 中线程和进程切换的开销: Linux 操作系统层面的进程和线程的实现都是task_struct描述符. task_struct 包含成员变量:内核态stack.  这些都存在3-4G虚拟地 ...

  6. ply2obj

    """ Simple script to convert ply to obj models """ import os from argp ...

  7. 【转帖】漏洞数量242:15,英特尔和AMD CPU谁更安全?

    漏洞数量242:15,英特尔和AMD CPU谁更安全? http://www.eetop.cn/cpu_soc/6946340.html 越来越多的用户开始怀疑哪种处理器可以最好地保护他们的计算机,数 ...

  8. 顺序表习题(1)-打印非递减数组a与b的升序并集(去除重复元素)

    void Print_Union(SqList a,SqList b) { , q = ; //初始化指针 ; //记录上一次打印的元素 while (p!=a.length&&q!= ...

  9. DFS集训

    2019-07-29 09:01:06 A PARTY A company has n employees numbered from 1 to n. Each employee either has ...

  10. 设置session销毁时间

    currentUser.getSession().setTimeout();