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.
一、题目描述:
给定一个十进制正整数n,写下从1开始,到n的所有整数,然后统计其中出现的所有“1”的个数。
例如:
n=13.
其中包含1的数字有1,10,11,12,13,一共有6个“1”,所以输出结果为6.
二、解题思路:
方法1:从1开始遍历到n,将其中每一个数中含有“1”的个数加起来,就会得到从1到n所有“1”的个数的和。
但是这种方法的时间复杂度为nlogn,当n较大时,运行时间会很长。
方法2:利用数学归纳法,直接对n进行分析,归纳总结规律
例如n=abcde五位数,我们分析百位的c,主要有以下三种情况:
1)当c == 0的时候,比如13013,此时百位出现1的是:00 100 ~ 00 199, 01 100~01 199,……,11 100~ 11 199,12100~12199共1300个,显然这个由高位数字决定,并且受当前位数影响,结果为:(高位数字)乘以(当前位数);
2)当c == 1的时候,比如13113,此时百位出现1的肯定包括c=0的情况,另外还需要考虑低位的情况即:00100 ~ 00113共114个,结果为:(高位数字)乘以(当前位数)+(低位数字)+1;
3)当c >= 2的时候,比如13213,此时百位出现1的是:00 100 ~ 00 199, 01 100~01 199,……,11 100~ 11 199,12 100 ~ 12 199,13100~13199,共1400个,这个仅由高位数字决定,结果为:(高位数字+1)乘以当前位数。
class Solution {
public:
int countDigitOne(int n) {
if (n <= 0) return 0;
long count = 0;
long factor = 1;
while (n / factor)
{
long lower = n%factor;
long cur = (n / factor) % 10;
long higher = n / (factor * 10);
switch (cur)
{
case 0:
count += higher*factor;
break;
case 1:
count += higher*factor + lower + 1;
break;
default:
count += (higher + 1)*factor;
}
factor *= 10;
}
return (int)count;
}
};