Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.
For example:
Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
Hint:
-
Beware of overflow.
这道题和数字有关,找出n以内数字中包含多少个1,题目难度为Medium。
假如n=9999,我们针对每一位进行统计,很容易看出0000~9999所有数字中,个位上每10个数字出现1个1,十位上每100个数字出现10个1,百位上每1000个数字出现100个1,等等。再以21045为例,个位上有多少个1出现呢?根据上面的分析,我们知道00000~21040所有数字中个位上共有2104个1(每10个数字出现1个1),而21041~21045所有数字中个位上只有1个1,个位就统计完了。十位上,00000~21000所有数字中十位上共有210*10个1(每100个数字出现10个1),而21001~21045所有数字中十位上共有10个1,十位也统计完了。百位上,00000~21000所有数字中百位上共有21*100个1(每1000个数字出现100个1),而21000~21045所有数字中百位上共有0个1,这里与个位和十位不同,因为百位是0,所以这段区间百位上不会有1。我们再看千位,00000~20000所有数字中千位上共有2*1000个1(每10000个数字出现1000个1),而20001~21045所有数字中千位共有46个1,这里与前面三者都不同,因为千位是1,所以这段区间上只有21000~21045上千位是1。
例子说到这里,相信大家已经想出了解决办法,根据每位上的数字来区别处理,0,1和大于1都是不同的。具体代码:
class Solution {
public:
int countDigitOne(int n) {
if(n <= 0) return 0;
long long cnt = 0;
long long wgt = 1;
long long num = n;
while(num > wgt/10) {
long long quo = num / (wgt*10);
long long rmd = num % (wgt*10);
cnt += quo*wgt;
if(rmd/wgt > 1) cnt += wgt;
else if(rmd/wgt == 1) cnt += (rmd%wgt)+1;
wgt *= 10;
}
return cnt;
}
};