【发布时间】:2014-04-23 10:07:59
【问题描述】:
找出从 0 到 n 的所有数字中出现了多少次“2”。
示例:n= 112 answer = 22
numbers : 2 , 12 , 20-29 , 32 ... 92 , 102 , 112
我想出了以下方法:
让k= n 的位数
f(k) = 从0 到10^k-1 的二的个数..
f(1) = 1 // 2
f(2) = 10*f(1)+ 10^(2-1) // 12 , 20 - 29 , 32 ... 92
f(3) = 10*f(2)+ 10^(3-1)
等等……
twos(int n , int k)
{
if(n<2)
return 0;
else if(n<10)
return 1;
msb = n/10^k
remainder = n%10^k
if(msb==2) // eg 230 , calculate 200 ... to 230 , and find twos from 0 on 199 and recursion on 30
return msb*(f(k)) + (remainder+1) + twos(remainder) // 2*(below 100) + 31 + tows(30)
else if (msb>=3)
return msb*(f(k)) + (10^k) + twos(remainder) // for 312 -> 3*(below 100) + 100 + twos(12)
else
return msb*(f(k)) + twos(remainder)
}
我的方法正确吗?
如果是这样,有没有比这更快的解决方案?
编辑:
对于这些测试用例,我的方法似乎是正确的,here 是模拟results :
第一栏:n,第二栏:蛮力,第三栏:我的方法
2 1 1
5 1 1
91 19 19
868 277 277
7783 3359 3359
55576 32718 32718
293911 242093 242093
10179297 7091858 7091858
59939789 51975959 51975959
【问题讨论】:
-
为了正确性,您是否使用哑循环进行检查?
-
一个循环给出了 n=10^7 的运行时错误,这里 n 可以到 10^18
-
您始终可以将解决方案的结果与蛮力实施的结果进行比较。理论上它不能证明您的解决方案对于每个输入都是正确的,但它可以提供一些信心...
-
@aseem:这个想法是用小数字测试它......例如:它是否为所有 n
-
只要你坚持使用 base-2,所有 n 的答案都是 0 ;p
标签: algorithm math language-agnostic