原来以为我会做,一直没有代码实现,结果真的开始做了发现我不会做!==
作者思路还是挺独特的!
int pow10(int l)
{
int k=1;
while(l>0)
{
k*=10;
l--;
}
return k;
}
int getNumberOf1(const char *str)
{
if(str[0]<='0' || str[0]>'9' || str[0]=='\0')return 0;
int first=str[0]-'0';
int l=strlen(str);
int num1OfFirst=0;
if(first>1)num1OfFirst=pow10(l-1);
else num1OfFirst=atoi(str+1)+1;
int numsOfOther=first*(l-1)*pow10(l-2);
return num1OfFirst+numsOfOther+getNumberOf1(str+1);
}
int NumberOf1Between1AndN_SolutionLX(unsigned int n)
{
char str[50];
sprintf(str,"%d",n);
return getNumberOf1(str);
}
numsOfOther=first*(l-1)*pow10(l-2);其中有点想不明白为啥要是l-1,后来想明白是在l-1个数字中选取一个设置为1,pow10(l-2)是其余数字设置次数。
有些数字比如1111,可能计算4次,但这也是可以的,因为本来这个数字就是要计算那么多次。
后来发现了另一个版本的计算1的个数,也是死路独特
叫我想可能就想不出的><
ANSWER
This is complicated... I hate it...
Suppose we have N=ABCDEFG.
if G<1, # of 1’s in the units digits is ABCDEF, else ABCDEF+1
if F<1, # of 1’s in the digit of tens is (ABCDE)*10, else if F==1: (ABCDE)*10+G+1, else (ABCDE+1)*10
if E<1, # of 1’s in 3rd digit is (ABCD)*100, else if E==1: (ABCD)*100+FG+1, else (ABCD+1)*100
… so on.
if A=1, # of 1 in this digit is BCDEFG+1, else it’s 1*1000000;
so to fast access the digits and helper numbers, we need to build the fast access table of prefixes and
suffixes.
int countOf1s(int n) {
int prefix[10], suffix[10], digits[10]; //10 is enough for 32bit integers
int i=0;
int base = 1;
while (base < n) {
suffix[i] = n % base;
digit[i] = (n % (base * 10)) - suffix[i];
prefix[i] = (n - suffix[i] - digit[i]*base)/10;
i++, base*=10;
}
int count = 0;
base = 1;
for (int j=0; j<i; j++) {
if (digit[j] < 1) count += prefix;
else if (digit[j]==1) count += prefix + suffix + 1;
else count += prefix+base;
base *= 10;
}
return count;
}