题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,,1一共出现了5次。
将输入的整数分为2部分,以后(n-1)位为分割点分为2部分,如21345分为1到1345和1346到21345,对第一部分递归调用算法,对后面的部分进行数学分析可以得出其中1的个数。首先最高位1出现的次数分为2种情况从1345到21345最高位出现了10000次为10000到19999,若最高位是1如12345,则最高位出现为10000到12345,共2346次。除最高位剩余段根据最高位的数字可分为多个段,每段的某一位为1时,其余各位能够为0~9,1出现总共次数为(最高位数字)*(剩余位的个数)*10^(剩余位个数-1)。代码如下:
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n)
{
//n的第一位数字
int firstposition=n;
int length=1;
while(firstposition>=10)
{
tmp=tmp/10;
length++;
}
if(n==0)
return 0;
if(length==1&&firstposition>1)
return 1;
int m=n-firstposition*PowerBase10(length-1);
//记录最高位出现1的次数
int numberfirst = 0;
if(tmp>1)
numberfirst = PowerBase10(length-1);
else if(tmp==1)
numberfirst = m+1;
//除了最高位其他位出现1的次数
int numberother = firstposition*(length-1)*PowerBase10(length-2);
//剩下的数字递归求解。
int numberRecursive = NumberOf1Between1AndN_Solution(m);
return numberfirst + numberother + numberRecursive;
}
int PowerBase10(int n)
{
int result = 1;
for(int i = 0; i<n; ++i)
result*=10;
return result;
}
};