1的数目
来源:互联网 发布:护卫神php套件 编辑:程序博客网 时间:2024/04/29 23:41
题目描述
给定一个十进制正整数N,求出从1到N的所有整数中包含1的个数。比如给定N=23,则包含1的个数为13。其中个位出现1的数字有1,11,21,共3个,十位出现1的数字有10,11...19共10个,所以总共包含1的个数为3+10 = 13个。
自然的解法
最自然的想法莫过于直接遍历1到N,求出每个数中包含的1的个数,然后将这些个数相加就是总的1的个数。需要遍历N个数,每次计算1的个数需要O(lgN)(以10为底),该算法复杂度为O(NlgN)。当数字N很大的时候,该算法会耗费很长的时间,应该还有更好的方法。
更好的解法
一个更好的解法建立在对该题目进行深入分析的基础上。一种特殊的情况是可以直接得出求解的公式的,而针对常规的情况则需要分情况考虑。
特殊的情况(N=10^K-1)
如果N为K位数,且N为K位数的最大值,则1~N中1的个数为K*10^(K-1)。假定N为3位数,且是3位数中最大的数999,则我们考虑从001-999。先让个位为1,则剩下的两个位置有10*10=10^2种可能,都可能为0-9中任何一个。同理,十位或百位为1,则剩下两个位置也有10^2种可能的取值,所以总的取值可能为3*10^2=300个1。注意一点,如果是求1~999中包含1的数字的个数,那就不同了。如11就只能算一个数字,而在前面的分析中是要算两次的。改成这样也很容易求解,考虑1~999共999个数字,其中不包含1的数字有9^3-1 = 728个,所以包含1的数字个数为999-728= 271个。
常规情况(N为任意正整数)
我们可以从1位数开始分析,慢慢找寻规律。
当N为1位数时,对于N>=1,1的个数F(N)为1。
当N为2位数时,则个位上1的个数不仅与个位数有关,还和十位数字有关。当N=23时,个位上1的个数有1、11、21共3个,十位上1的个数为10,11...19共10个,所以1的个数F(N) = 3+10 = 13。如果N的个位数大于等于1,则个位出现1的次数为十位数的数字加1;如果N得个位数为0,则个位出现1的次数等于十位数的数字。
十位数上出现1的次数类似,如果N的十位数字等于1,则十位数上出现1的次数为各位数字加1;如果N的十位数字大于1,则十位数上出现1的次数为10。
当N为3位数时,同样分析可得1的个数。如N=123,可得1出现次数=13+20+24 = 57。
当N为4,5...K位数时,我们假设N=abcde,则要计算百位上出现1的数目,则它受到三个因素影响:百位上的数字,百位以下的数字,百位以上的数字。
如果百位上数字为0,则百位上出现1的次数为更高位数字决定。如N=12013,则百位出现1的数字有100~199, 1000~1199, 2100~2199...11100~111999共1200个,等于百位的更高位数字(12)*当前位数(100)。
如果百位上数字为1,则百位上出现1的次数不仅受更高位影响,还受低位影响。如12113,则百位出现1的情况共有1200+114=1314个,也就是高位影响的12*100+低位影响的113+1=114个。
如果百位上数字为其他数字,则百位上出现1的次数仅由更高位决定。如12213,则百位出现1的情况为(12+1)*100=1300。
有以上分析思路,写出下面的代码。其中low表示低位数字,curr表示当前考虑位的数字,high表示高位数字。
一个简单的分析,考虑数字123,则首先考虑个位,则curr为3,低位为0,高位为12;然后考虑十位,此时curr为2,低位为3,高位为1。其他的数字可以以此类推。
typedef unsigned long long ULONG;ULONG numOfone(ULONG n){ ULONG factor = 1, cnt = 0; //factor为乘数因子 ULONG low=0, curr=0, high=0; while (n / factor != 0) { low = n - n/factor * factor; //low为低位数字,curr为当前考虑位的数字,high为高位数字 curr = n/factor % 10; high = n/(factor * 10); switch(curr) { case 0: //当前位为0的情况 cnt += high * factor; break; case 1: //当前位为1的情况 cnt += high * factor + low + 1; break; default: //当前位为其他数字的情况 cnt += (high+1) * factor; break; } factor *= 10; } return cnt;}
递归解法
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- BOP - 1的数目
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- 1的数目
- “1”的数目
- 1的数目
- iphone开发NSString字符串常用方法
- Windows/Ubuntu 在Eclipse中配置NDK自动编译环境builders
- 负数的左移与右移
- mysql cursor 游标
- 今日win7的oracle11g客户端通过tns远程登录linux的rac失败
- 1的数目
- Deadlock
- C++,类的构造函数重载,语法练习
- 素数最短距离问题
- 2440初始化存储器原理(接上一篇)
- sencha touch如何动态改变panel里面的background-image元素
- PKU OJ题目分类 + 背包算法
- 创新工场笔试+面试小结
- 黑马程序员九、GUI