http://zhedahht.blog.163.com/blog/static/25411174200732494452636/
http://www.cnblogs.com/GoAhead/archive/2012/05/28/2521415.html
http://blog.csdn.net/sjf0115/article/details/8600599
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。
分析:这是一道广为流传的google面试题。
普通n*lg(n)的解法。
/////////////////////////////////////////////////////////////////////////////
// Find the number of 1 in an integer with radix 10
// Input: n - an integer
// Output: the number of 1 in n with radix
/////////////////////////////////////////////////////////////////////////////
int NumberOf1(unsigned int n)
{
int number = 0;
while(n)
{
if(n % 10 == 1)
number ++;n = n / 10;
}return number;
}/////////////////////////////////////////////////////////////////////////////
// Find the number of 1 in the integers between 1 and n
// Input: n - an integer
// Output: the number of 1 in the integers between 1 and n
/////////////////////////////////////////////////////////////////////////////
int NumberOf1BeforeBetween1AndN_Solution1(unsigned int n)
{// T(n) = n*lg(n)
int number = 0;// Find the number of 1 in each integer between 1 and n
for(unsigned int i = 1; i <= n; ++ i)
number += NumberOf1(i);return number;
}
更加巧妙的lg(n)的解法。
简单的方法就是按照给位进行分析:
在个位出现1的个数=n/10+(个位=0,0;个位>1,1;个位=1,低0位+1);
十位位出现1的个数=n/100*10+(十位=0,0;十位>1,10;十位=1,低一位+1);
百位出现1的个数=n/1000*100+(百位=0,0;百位>1,100;百位=1,低两位+1);
等等
算法的复杂度仅仅和位数有关。
设第i位出现1的个数为s(i),N为输入整数n的位数。则总和sum= s(1)+…s(i)+…s(N)即为所求。
设bi为整数n的第i位数字,第i位之后的剩余数字为ri;
s(i) = A + B
A = n/10i*10i-1
bi=( n/10i-1)%10
ri= n/10i-1
b(i)==0 ,则B=0
b(i)==1 ,则B=ri+1
b(i)>1 ,则B=10i-1
int PowerBase10(unsigned int n)
{// 10^n
int result = 1;
for(unsigned int i = 0; i < n; ++ i)
result *= 10;return result;
}int b10(unsigned int n)
{
return PowerBase10(n);
}int NumberBitCount(unsigned int n)
{
int N = 0;
while(n)
{
n = n/10;
N++;
}
return N;
}int NumberOf1BeforeBetween1AndN_Solution2(unsigned int n)
{// T(n) = o(N) = o(lgn)
int N = NumberBitCount(n);
int si,sum=0;
int A,B,bi,ri;
for (int i=1;i<=N;i++)
{
A = n/b10(i)*b10(i-1);
bi = n/b10(i-1)%10;
ri = n%b10(i-1);
if (bi==0)
{
B = 0;
}
else if (bi==1)
{
B = ri+1;
}
else if (bi>1)
{
B = b10(i-1);
}
si = A+B;
sum +=si;
}return sum;
}
25.在从1到n的正数中1出现的次数