原题地址:https://leetcode-cn.com/problems/number-of-digit-one/
题目描述:
给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。
示例:
输入: 13
输出: 6
解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13 。
解题方案:
纯数学类型的题目,需要寻找规律并进行总结,过程比较繁琐,学习网上大佬的方法:https://blog.csdn.net/kyfant/article/details/82658273?utm_source=blogxgwz8
代码:
class Solution {
public:
int GetContribution1(int nDigit){
if (nDigit == 1) return 0;
int nTem = nDigit - 2;
int nRes = 1;
int i = 1;
while(nTem -- > 0)
nRes = nRes * 10 + power10(i++);
return nRes;
}
// 10的n次幂
int power10(int n)
{
int nTem = n;
int res = 1;
while (nTem > 0)
{
res *= 10;
nTem--;
}
return res;
}
int countDigitOne(int n) {
int nRes = 0;
// 定义一个数组记录输入的每一位
vector<int> vecNum;
int nTem = n;
while(nTem)
{
vecNum.push_back(nTem % 10);
nTem /= 10;
}
nTem = n;
while(vecNum.size() > 0)
{
// 当前共有几位
int nCurWei = vecNum.size();
// 当前最高位是多少
int nHigh = vecNum.back();
// 当前最高位如果是0,则对1没有贡献
if (nHigh > 0)
{
// 贡献的第一部分
nRes += GetContribution1(nCurWei) * nHigh;
// 贡献的第二部分
if (nHigh == 1)
nRes += nTem % power10(nCurWei - 1) + 1;
else
nRes += power10(nCurWei - 1);
// nTem表示去除最高位剩下的数
nTem %= power10(nCurWei - 1);
}
vecNum.pop_back();
}
return nRes;
}
};