(C++)剑指offer-31:整数中1出现的次数(时间效率)
2018-02-14 20:41
369 查看
剑指offer-31:整数中1出现的次数(从1到n整数中1出现的次数)
目录
剑指offer-31整数中1出现的次数从1到n整数中1出现的次数目录
1题目描述
2题目解析及答案
1题目描述
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
2题目解析及答案
class Solution { public: int NumberOf1Between1AndN_Solution(int n){ int ones = 0; for (long long m = 1; m <= n; m *= 10) ones += (n/m + 8) / 10 * m + (n/m % 10 == 1) * (n%m + 1); return ones; } };
int a = n/m, b = n%m;
注解:参考leetcode(包括求1~n的所有整数中2,3,4,5,6,7,8,9出现的所有次数)
通过使用一个位置乘子m 遍历数字的位置, m 分别为1,10,100,1000…etc.(m<=n)
对于每个位置来说,把10进制数分成两个部分
(1)比如说当m=100的时候, 把十进制数 n=3141592 分成 a=31415 和 b=92 ,以此来分析百位数为1时所有数的个数和。
m=100时,百位数的前缀为3141
当百位数大于1时,为3142*100,因为当百位数大于1时,前缀可以为0,即百位数可以从100到199,共100个数;
当百位数不大于1时,为3141*100;
如何判断百位数是否大于1?
假设百位数为x,若(x+8)/10等于1,则大于1,若(x+8)/10等于0,则小于1。
因此前缀可用(n/m + 8)/10 *m来计算(若计算2的个数,可以改为(n/m + 7)/10*m,若计算3的个数,改为(n/m + 6)/10*m,…以此类推)。
(2)再例如m=1000时,n分为a=3141和 b=592;
千位数的前缀为314,千位数不大于1,故前缀计算为314*1000;
因为千位数为1,再加b+1(0到592)。即千位数为1的所有书的个数和为314*1000+592+1;公式(n/m + 8)/10*m + b +1。
注意:只有n的第m位为1时需要计算后缀,后缀计算为 (n/m%10==1)*(b+1)
即(n/m%10==1)判断第m位是否为1,若为1,则加上(b+1),若不为1,则只计算前缀。
(若计算2的个数,可以改为(n/m%10==2)(b+1),若计算3的个数,可以改为(n/m%10==3)(b+1)…以此类推)
相关文章推荐
- (C++)剑指offer-28:数组中出现次数超过一半的数字(时间效率)
- ##剑指offer 5.2 时间效率3 -1到N整数中1出现的次数
- 剑指offer-第五章优化时间和空间效率(从1到n的整数中1出现的次数)
- 剑指offer-5-面试32:从 1 到 n 整数中 1 出现的次数(时间效率)
- 【剑指offer】5.2时间效率——面试题32:从1到n整数中1出现的次数
- 剑指offer-31.整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指Offer面试题31连续子数组的最大和,面试题32从1到n整数中1出现的次数
- 剑指Offer_31_整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer 5.2 时间效率1 - 数组中出现次数超过一半的数字
- 剑指Offer——(31)整数中1出现的次数(从1到n整数中1出现的次数)
- (C++)剑指offer-34:第一个只出现一次的字符位置(时间空间效率的平衡)
- 【剑指offer】5.2时间效率——面试题29:数组中出现次数超过一半的数字
- 剑指offer-第五章优化时间和空间效率(数组中出现次数超过一半的数字)
- 剑指Offer—31—整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer 29题 【时间效率】数组中出现次数超过一半的数字
- 剑指Offer(43)1~n整数中1出现的次数
- 剑指offer面试题32:从1到n整数中1出现的次数
- 【剑指offer】Q32:从1到n整数1出现的次数(python)
- 剑指offer----整数中1出现的次数(从1到n整数中1出现的次数)
- 剑指offer:整数中1出现的次数(python)