力扣对应题目链接:233. 数字 1 的个数 - 力扣(LeetCode)
牛客对应题目链接:整数中1出现的次数(从1到n整数中1出现的次数)_牛客题霸_牛客网 (nowcoder.com)
一、《剑指Offer》对应内容
二、分析题目
先随便写个数,来找个规律。以 3421 为例:
1、个位
什么时候个位会出现 1 呢,当然只有一种可能,那就是 1 ,那么有多少个 个位 为 1的数呢?有342个 加 1(这个 1 为 数字 1) 即 342 * 1 + 1个 。
那如果是 3420 呢?那就有 342 个个位为 1 的数
2、十位
那么对于十位,我们什么时候会出现 1 呢? 一共有 10,11,12......19。 10个数会出现 1, 那么有多少个 这样的数呢? 有 34 个 这样的数 加 十位为 1的十个数 即 34 * 10 + 10。
那如果是 3400 呢 ? 那就只有 34 * 10 个了,因为十位为 0
3、百位
以此类推,会有 3 * 100 加上 百位为 1 的个数 即 3 * 100 + 100
那如果是 3000 呢 ? 那就只有 3 * 100 个了,因为百位为 0
4、千位
以此类推,会有 0 * 1000 加上 千位为 1 的个数 即 0 * 100 + 1000
那如果是 0000 呢 ? 那就只有 0 * 1000 个了,因为千位为 0 , 很显然最高为不可能为零。
三、代码
//力扣
class Solution {
public:
int countDigitOne(int n) {
int cnt=0;
int back=0;
for(int i=0; n!=0; i++)
{
int front=n/10;
if(front*10+1<n) front++;
else if(front*10+1==n) cnt+=back+1;
cnt+=front*pow(10, i);
back+=n%10*pow(10, i);
n/=10;
}
return cnt;
}
};
//牛客
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n) {
int cnt=0;
int back=0;
for(int i=0; n!=0; i++)
{
int front=n/10;
if(front*10+1<n) front++;
else if(front*10+1==n) cnt+=back+1;
cnt+=front*pow(10, i);
back+=n%10*pow(10, i);
n/=10;
}
return cnt;
}
};