剑指offer-面试题32 从1到n整数中1出现的次数

原来以为我会做,一直没有代码实现,结果真的开始做了发现我不会做!==

作者思路还是挺独特的!


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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值