问题描述:
Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.
Example:
Input: 13 Output: 6 Explanation: Digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
解题思路:
这道题虽然题短,答案短,但它耗费我的时间一点都不短。
参考了Stefan Pochman 和 xudli的答案以及解释,集众人之力,我终于弄明白了。
针对每个位置讨论它是1的个数:
每10个数: 个位数上 1个1
每100个数: 十位数上十个1: 10-19
每1000个数:百位数上100个1: 100-199
诸如此类。
我们用m将数字分成两部分,a和b
a = n /100即前半部分
b = n % 100 即后半部分
用xudli的例子来理解当a的最后一位分别为0,1,以及大于2时的不同之处:
case 1: n=3141092, a= 31410, b=92. 计算百位上1的个数应该为 3141 *100 次. (因为每1000个有100个百位为1!)
case 2: n=3141192, a= 31411, b=92. 计算百位上1的个数应该为 3141 *100 + (92+1) 次. (要加上3141 100~ 3141 92次)
case 3: n=3141592, a= 31415, b=92. 计算百位上1的个数应该为 (3141+1) *100 次. (因为会涵盖1,所以要再加100)
用(a + 8)/10来判断是否是大于等于2,若大于等于2 还会自动加1.
代码:
class Solution { public: int countDigitOne(int n) { int ret = 0; for(long long m = 1; m <= n; m *= 10){ int a = n/m, b = n%m; ret += (a+8)/10 * m + (a%10 == 1) * (b+1); } return ret; } };