问题出自编程之美
给定一个十进制正整数N,写下从1开始,到N的所有整数,然后数一下其中出现的所有1的个数
解法:
设正整数N,a1a2a3...an为其十进制数表示
出现的所有1的个数,等于a1,a2,a3....an上出现的所有的1的个数总和
我们先分析an上出现的1的个数
首先看几个例子
34,245
对于34,个位上为1的数有1,11,21,31,总数为4个
对于245,个位上为1的数有1,11,21,31,41,51,61,71,81,91,101,111,121,,,,241,总数为25个
个位上出现1的数目只和高位有关,即an上出现1的个数=a1a2...a(n-1)+1
然后我们继续分析an-1上出现的1的个数
仍然看例子34,245
对于34,十位上为1的数有10-19,总数为10个
对于245,十位上为1的数有10-19,110-119,210-219,总数为30个
对于215,十位上为1的数有10-19,110-119,210-215,总数为26个
对于205,十位上为1的数有10-19,110-119,总数为20个
通过205,215,245三个数的分析得出结论
当an-1=0时,an-1上出现1的数目=(a1a2...an-2)*10
当an-1=1时,an-1上出现1的数目=(a1a2...an-2)*10+an+1
当an-1>=2时,an-1上出现1的数目=(a1a2...an-2+1)*10
用以上分析方法可在O(lgN)时间内算出结果