1 题目描述

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

2 思路和方法

  统计整数n中的每个十进制位中1出现的次数,再累加起来。 对于每一位来说可以把一个数拆分为 前面( begin)+中间( middle)+后面(end )。 1234的百位 = 1+2+34

  (编程之美)找数字规律,五行代码:
  首先要知道以下规律:

  从 1 至 10,在它们的个位数中,1出现了 1 次;
  从 1 至 100,在它们的十位数中,1出现了 10 次;
  从1至1000,在它们的百位数中,1出现了100次;

  依次类推,从 1 至 10 i,在它们的左数第二位(右数第 i 位),1出现了 (10 i-1)次。这个规律很容易验证。

  我们以n=21345为例来使用这个规律。首先分析个位1出现了几次。从1~21340数字1总共出现了2134*1次,最后剩下21341、21342、21343、21344、21345,所有还出现1次数字1。所以个位共出现1的次数为2135次。

  接下来分析十位中1出现了几次。从1~21300数字1总共出现了213*10次,剩下的数字从 21301至 21345,它们最大的十位数是 4 > 1,所以还有10次。所以十位共出现2140次。

  接下来分析百位中1出现了几次。从1至21000数字1共出现了21*100次。剩下的数字是21001~21345,最大的百位数是3,大于1,所以还有100次。所以百位中1共出现了2200次。

  接下来分析千位中1出现了几次。从120000数字1共出现了2*1000次。剩下的数字是2000121345,最大的千位数是1,等于1,这种情况稍微比较复杂,因为它并不包括所有千位为1的数字,即1000个,这种情况取决于低位上的数字,为345+1=346次。最后总计2346次。

  接下来分析万位中1出现了几次。因为它是最高位了因此直接看最高位的数字,即2,2>1。很显然10000~19999中1在万位共出现了10000次。如果最高位等于1那就和上一步的思想一样。

通过以上几步的分析我们可以得出结果:1~21345中1共出现了18821次。

3 C++核心代码

简洁版:https://blog.csdn.net/typantk/article/details/88386888(讲解的太好了)

 class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
int ones = ;
for (long m = ; m <= n; m *= )
ones += (n/m + ) / * m + (n/m % == ? n%m + : );
return ones;
}
};

代码较多

 class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
int temp = n;
int last;
int result = ;
int base = ;
while(temp){
last = temp%; //个位数是否为1
temp = temp/; //去掉个位数
result += temp*base;
if (last==){
result += n%base + ;
}
else if(last>){
result += base;
}
base *= ;
}
return result;
}
};

4. C++完整代码

 #include <iostream>

 using namespace std;

 long long fun(long long n)
{
if (n < )
return ;
long long count = , num = , begin, middle, end, m;
begin = n;
middle = ;
end = ;
while (begin)
{
begin = n / count;
m = n%count;
middle = m / (count / );
end = m % (count / );
if (middle > )
num = num + (count / ) * (begin + );
else if (middle == )
num = num + (count / ) * begin + (end + );
else
num = num + (count / ) * begin;
count = count * ;
}
return num;
} int main()
{
long long n, m;
while (scanf("%lld %lld", &n, &m) != EOF)
{
if (n>m)
printf("%lld\n", fun(n) - fun(m - ));
else
printf("%lld\n", fun(m) - fun(n - ));
}
printf("%\n"); system("pause");
return ;
}

https://blog.csdn.net/zhoubin1992/article/details/47361969

参考资料

https://blog.csdn.net/typantk/article/details/88386888(讲解的太好了)

https://blog.csdn.net/u012477435/article/details/83351659#_873

https://blog.csdn.net/qq_25343557/article/details/79330274(讲解的太好了)

剑指offer31:整数中1出现的次数(从1到n整数中1出现的次数)的更多相关文章

  1. 剑指offer-31:整数中1出现的次数(从1到n整数中1出现的次数)

    参考: https://troywu0.gitbooks.io/interview/整数中出现1的次数(从1到n整数中1出现的次数).html 题目描述 求出1~13的整数中1出现的次数,并算出100 ...

  2. 剑指Offer-31.整数中1出现的次数(从1到n整数中1出现的次数)(C++/Java)

    题目: 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了.A ...

  3. 《剑指offer》第四十三题(从1到n整数中1出现的次数)

    // 面试题43:从1到n整数中1出现的次数 // 题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如 // 输入12,从1到12这些整数中包含1 的数字有1,10,11和12 ...

  4. 【剑指Offer面试编程题】题目1349:数字在排序数组中出现的次数--九度OJ

    题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数组的大小.1<=n <= 10^6. 第二行有n个整数,表示数组元素,每个元素均 ...

  5. 剑指 Offer 30. 包含min函数的栈 + 双栈实现求解栈中的最小值

    剑指 Offer 30. 包含min函数的栈 Offer_30 题目描述: 题解分析: 题目其实考察的是栈的知识,本题的目的是使用两个栈来求解最小值. 第二个栈主要用来维护第一个栈中的最小值,所以它里 ...

  6. 剑指offer--31.二叉树中和为某一值的路径

    深度优先搜索 --------------------------------------------------------------------------------------------- ...

  7. 剑指offer——python【第49题】把字符串转换成整数

    题目描述 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数. 数值为0或者字符串不是一 ...

  8. 《剑指offer》第六十七题(把字符串转换成整数)

    // 面试题67:把字符串转换成整数 // 题目:请你写一个函数StrToInt,实现把字符串转换成整数这个功能.当然,不 // 能使用atoi或者其他类似的库函数. #include <ios ...

  9. 剑指Offer的学习笔记(C#篇)-- 数字在排序数组中出现的次数

    题目描述 统计一个数字在排序数组中出现的次数. 一 . 题目分析 该题目并不是难题,但该题目考察目的是正确的选择合适的查找方法.题目中有一个关键词是:排序数组,也就是说,该数组已经排好了,我一开始直接 ...

随机推荐

  1. python 设计模式学习代码记录

    @工厂模式class Beijing: def printreslut(self): print("ok") class Shanghai: def printreslut(sel ...

  2. 和小哥哥一起刷洛谷(8) 图论之Floyd“算法”

    关于floyd floyd是一种可以计算图中所有端点之间的最短的"算法",其伪代码如下: for(所有起点i) for(所有终点j) 如果i=j: i到j最短路设为0 如果i与j相 ...

  3. Android studio: Android Studio 3.5格式化布局代码时错乱

    Android studio 又来搞事情了,更新到3.5版本后,格式化布局文件代码时,布局文件代码竟然会发生变化,意思是不让格式化代码了呗? 垃圾的IDE. 解决办法: “File”-"Se ...

  4. JEECG Hibernate 自动更新 持久化

    Hibernate不调用update却自动更新 - 七郎 - 博客园http://www.cnblogs.com/yangy608/p/4073941.html hibernate自动更新持久化类的问 ...

  5. markdown2的key

    分享一个MarkDown2的授权key   邮箱地址: Soar360@live.com 授权秘钥: GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGIm ...

  6. Flutter ListView 列表组件

    列表常见的情况: 1.垂直列表 2.垂直图文列表 3.横向列表 4.动态列表 名称 类型 说明 scrollDirection Axis Axis.horizontal 横向列表 Axis.verti ...

  7. Spring 定时任务 注解版

    Task类: ManageSql.Java对应代码: package com.axb.cheney.task; import java.sql.ResultSet; import java.sql.S ...

  8. spring 使用@Bean装配Bean

    通过@Component装配Bean,但是@Component只能注解在类上,不能注解到方法上.对于Java而言,大部分的开发都需要引入第三方的包(jar文件),而且往往并没有这些包的源码,这时候将无 ...

  9. 【线段树】HDU 1166 敌兵布阵

    这道题目是线段树里面最基础的单点更新问题. 设计的知识点包括线段树的单点更新和区间查询. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 G++ ...

  10. bootstrapTable:获取选中行的数据

    必须要有checkbox:true和singleSelect:true,然后就可以通过var row=$("#mytab").bootstrapTable('getSelectio ...