题目描述:

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

  解题思路:

  本题一个最简单直观的做法是:累加从1到n每个整数中1出现的次数,而对于每个整数,可以通过对10求余判断个位数字是不是1,然后除10再判断下一位。这种思路很简单,但是对于数字n,有O(logn)位,n个数字依次判断的时间复杂度为O(nlogn),计算量比较大。

  这里我们采用一种数学方法,对数n的每一位单独讨论,记每一位的值为weight。

  首先,我们考虑个位,个位每隔10个数就会出现一个1,如1,11,21等等,以10为分隔阶梯,我们可以知道每次从1到10 的一轮中,会出现一个1,出现了几轮取决于它前面的数,最后根据个位上的数会出现一个不完整的一轮,若为0,这说明没有出现1,否则出现了1。所以个位上总共出现的1的个数为:n/10 + (n%10==0?0:1)。

  然后考虑十位,十位与个位的不同之处在于:从1到n,每增加10,十位的weight才会增加1,所以,一轮0-9周期内,1会出现10次,也就是从10到19这十个数。这样的数每隔100次才会出现一次,出现了几轮取决于它前面的数。同样最后会有一个不完整的一轮,这取决于十位上的数字,如果十位数weigth大于1,说明最后一轮的完整十次都出现了;weight为0,说明最后一轮没有出现1;如果正好为1,那么取决于个位数字是几。

  进而再考虑更高位,分析方法和十位类似。

  总结起来,我们可以得到以下规律:

   记当前位值为weight,它前面的数为round(代表了循环轮次),后面的数为former(初始为0,代表最后的一个不完整轮次),当前位权为base。

  • 若weight为0,则1出现次数为round*base
  • 若weight为1,则1出现次数为round*base+former+1
  • 若weight大于1,则1出现次数为rount*base+base

  举例:

![](https://img2018.cnblogs.com/blog/1608161/201905/1608161-20190506215543354-862198237.png)

  534 = (个位1出现次数)+(十位1出现次数)+(百位1出现次数)=(53*1+1)+(5*10+10)+(0*100+100)= 214

  504 = (50*1+1)+(5*10)+(0*100+100) = 201

  514 = (51*1+1)+(5*10+4+1)+(0*100+100) = 207

  编程实现(Java):

 	public int NumberOf1Between1AndN_Solution(int n) {
int count=0;
int weight=0; //位值
int base=1; //权重
int former=0;
int round=n;
while(round!=0){
weight=round%10;
round=round/10;
former = n%base;
if(weight>1)
count += (round*base+base);
else if(weight==1)
count += (round*base+former+1);
else
count += (round*base);
base *= 10;
}
return count;
}

  本文参考: CSDN博客yi_afly,特此说明

【剑指Offer】31、从1到n整数中1出现的次数的更多相关文章

  1. 剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数)

    剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数) 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https:// ...

  2. 【Java】 剑指offer(43) 从1到n整数中1出现的次数

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例 ...

  3. 剑指offer 面试题43. 1~n整数中1出现的次数

    leetcode上也见过一样的题,当时不会做 看了一下解法是纯数学解法就没看,结果剑指offer上也出现了这道题,那还是认真看下吧 对于数字abcde,如果第一位是1,比如12345,即计算f(123 ...

  4. 《剑指offer》面试题56 - II. 数组中数字出现的次数 II

    问题描述 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次.请找出那个只出现一次的数字. 示例 1: 输入:nums = [3,4,3,3] 输出:4 示例 2: 输入:nums ...

  5. 《剑指offer》面试题56 - I. 数组中数字出现的次数

    问题描述 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 示例 1: 输入:nums = [4,1 ...

  6. 剑指 Offer 31. 栈的压入、弹出序列 + 入栈顺序和出栈顺序的匹配问题

    剑指 Offer 31. 栈的压入.弹出序列 Offer_31 题目详情: 解析: 这里需要使用一个栈来模仿入栈操作. package com.walegarrett.offer; /** * @Au ...

  7. 剑指 Offer 31. 栈的压入、弹出序列

    剑指 Offer 31. 栈的压入.弹出序列 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如,序列 {1,2,3,4,5} 是某 ...

  8. 力扣 - 剑指 Offer 67. 把字符串转换成整数

    题目 剑指 Offer 67. 把字符串转换成整数 思路1 根据题意,要解决这题,首先要判断的条件有: 不包括首位空格 第一位必须为:+.-.数字三者其一,否则不合法 数字必须连续的,如果遇到非数字, ...

  9. 剑指Offer - 九度1356 - 孩子们的游戏(圆圈中最后剩下的数)

    剑指Offer - 九度1356 - 孩子们的游戏(圆圈中最后剩下的数)2014-02-05 19:37 题目描述: 每年六一儿童节,JOBDU都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.H ...

  10. 剑指Offer - 九度1514 - 数值的整数次方

    剑指Offer - 九度1514 - 数值的整数次方2013-11-30 00:49 题目描述: 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponen ...

随机推荐

  1. firedac数据集控件的公共祖先类——TFDAdaptedDataSet

    firedac数据集控件的公共祖先类——TFDAdaptedDataSet TFDQuery = class(TFDCustomQuery)TFDCustomQuery = class(TFDRdbm ...

  2. Java:解决Servlet的UTF8编码问题

    要让Servlet支持UTF8,需要在doGet或者doPost中添加如下一条语句: request.setCharacterEncoding("UTF-8");

  3. jQuery toast message 地址 使用

    jQuery toast message 地址 使用 https://github.com/akquinet/jquery-toastmessage-plugin/wiki

  4. [CSS3] Use Sticky Positioning for Section Headers

    We can take advantage of sticky positioning to keep a section header at the top of the page while th ...

  5. 苹果的编程语言--Swift

    今天(2014-6-3)凌晨WWDC2014揭幕了,带来了新语言Swift,据说非常牛逼...所以就找了几个不错的link跟大家分享. 1.Swift的简单介绍,主要介绍了Swift的简单而经常使用的 ...

  6. 二分查找(c &amp; c++)

    typedef int ElemType; C版本号 [递归版本号] int binSearch2(ElemType List[] ,int x,int head,int tail){ //递归版本号 ...

  7. Ext.tree.Panel实现单选,多选

    Extjs var productCategoryTreeLookUpFn = function(callback) { var productCategoryLookUpWindow; var pr ...

  8. luogu1005 矩阵取数游戏

    题目大意 一个矩阵,每次从每一行的行首或行尾取一个数,每一行的价值为 取的数*2^当前取数的次数,每一次的价值为每一行的价值的和.求得到的价值的最大值. 思路 #include <cstdio& ...

  9. C/C++大小端模式与位域

    一.大端小端: 1.大端:指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中 例如:0x12345678 在内存中的存储为  : 0x0000 0x0001 0x0002 0x00 ...

  10. curses-键盘编码-openssl加解密【转】

    本文转载自;https://zhuanlan.zhihu.com/p/26164115 1.1 键盘编码 按键过程:当用户按下某个键时, 1.键盘会检测到这个动作,并通过键盘控制器把扫描码(scan ...