本题可分为两道题,如下:
题目描述:求出1~n的整数中1出现的次数,例如1~13中包含1的数字有1、10、11、12、13。此时如果按照1出现的次数,那么将会有6次。如果是含有1的数字的个数,则为5个。下面将分别按照不同的方式来给出代码。
1. 1~13中含有1的数字为5个
int NumberOf1Between1AndN_Solution1(int n)
{
int bit = -1;
int n_copy = n;
int maxbitNum = 0;
while (n_copy)
{
maxbitNum = n_copy % 10;
n_copy = n_copy / 10;
bit++;
}
//按照首字母为1和非1大来分,非1便是在2-9之间。具体思路就是如果是1-999之间的数字,那么十位百位分位取值只要含有1就可以,也就转化为所有数组组合减去所有数字都不含有1的组合,即10*10*10-9*9*9。
if (maxbitNum > 1)
{
return maxbitNum * pow(10, bit) - (maxbitNum - 1) * pow(9, bit) + NumberOf1Between1AndN_Solution1(n - maxbitNum * pow(10, bit));
}
else
{
return pow(10, bit) - pow(9, bit) + n - maxbitNum * pow(10, bit) + 1;
}
}
2. 1~13中含有1的个数为6个,即11算含有两个1
int NumberOf1Between1AndN_Solution(int n)
{
if (n < 10 && n > 0)
{
return 1;
}
else if (n <= 0)
{
return 0;
}
else
{
int bit = -1;
int n_copy = n;
int maxbitNum = 0;
while (n_copy)
{
maxbitNum = n_copy % 10;
n_copy = n_copy / 10;
bit++;
}
//大致思路相同,但是做法不同。直接找含有1的数字,而且含有1的个数多的数字要算较多遍。
if (maxbitNum > 1)
{
return pow(10, bit) + maxbitNum * bit * pow(10, bit - 1) + NumberOf1Between1AndN_Solution(n - maxbitNum * pow(10, bit));
}
else
{
return bit * pow(10, bit - 1) + n - maxbitNum * pow(10, bit) + 1 + NumberOf1Between1AndN_Solution(n - maxbitNum * pow(10, bit));
}
}
}