题目:力扣233.数字1的个数
给定一个整数 n
,计算所有小于等于 n
的非负整数中数字 1 出现的个数。
示例 1:
输入:n = 13
输出:6
示例 2:
输入:n = 0
输出:0
当下第一反应就是硬推
class Solution {
public:
int countDigitOne(int n) {
long i=1,s=0;
for(i;i<=n;i++)
{
num=i;
while(num)
{
if(num%10==1) s++;
num/=10;
}
}
return s;
}
};
很显然,这是会超时的,所以我们pass掉。
接着,就推理逻辑。
我想到我们分别计算各个位置上的1的出现的次数,然后求和,就得到了以下答案。
class Solution {
public:
int countDigitOne(int n) {
int num=n,i=1,s=0;
while(num)
{
if(num%10==0)
s=s+(num/10)*i;
if(num%10==1)
s=s+(num/10)*i+(n%i)+1;
if(num%10>1)
s=s+ceil(num/10.0)*i;
num=num/10;
i*=10;
}
return s;
}
};
这是第一遍打出来的代码,但是因为int的取值问题,题目中给到的数据太大导致溢出,所以我稍加修改:
class Solution {
public:
int countDigitOne(int n) {
long num=n,i=1,s=0;
while(num)
{
if(num%10==0)
s=s+(num/10)*i;
if(num%10==1)
s=s+(num/10)*i+(n%i)+1;
if(num%10>1)
s=s+ceil(num/10.0)*i;
num=num/10;
i*=10;
}
return s;
}
};
这就是最终结果。
最后看一下用时和内存占用:
还是不错了的,能力所止。
ZHJ