问题:
我看到过这样的问题:
这些问题很相似,都是要找出数字范围 [0, N]
内数字 K(K=0,1,2,...,9)
出现的总次数。
例如:
- 输入:
K=2, N=35
- 输出:
14
- 详细:
[0,35]
范围内的数字2
有:2、12、20、21、22、23、24、25、26、27、28、29、32
,注意,22
将被计算两次(因为22
包含两个2
)
我们所拥有的:
每个问题都有解决方法(如果你搜索一下就能找到)。通常,需要 O(log N)
时间来通过递归地考虑最高位数字等方式解决这些问题。例如,在0和N之间计算出数字2的个数可以通过以下过程解决(摘自这里):
// Take n = 319 as example => 162
int numberOf2sBetween0AndN(int n)
{
if (n < 2)
return 0;
int result = 0;
int power10 = 1;
while (power10 * 10 < n)
power10 *= 10;
// power10 = 100
int msb = n / power10; // 3
int reminder = n % power10; // 19
/*** Count # of 2s from MSB ***/
if (msb > 2) // This counts the first 2 from 200 to 299
result += power10;
if (msb == 2) // If n = 219, this counts the first 2 from 200 to 219 (20 of 2s).
result += reminder + 1;
/*** Count # of 2s from reminder ***/
// This (recursively) counts for # of 2s from 1 to 100; msb = 3, so we need to multiply by that.
result += msb * numberOf2s(power10);
// This (recursively) counts for # of 2s from 1 to reminder
result += numberOf2s(reminder);
return result;
}
问题:
请注意,在上述代码中,我们不能简单地将所有2
的部分更改为1
,以解决计算0
和N
之间的1
的数量的问题。似乎我们必须针对不同的情况(非平凡)进行处理。
是否有一般性的程序可以处理所有K
(即K=0,1,2,...,9
)的情况,类似于以下函数?
int numberOfKsBetween0AndN(int k, int n)
测试用例:
如果您想要检查你的解决方案,这里是一些测试用例:
k=1, N=1
: 1k=1, N=5
: 1k=1, N=10
: 2k=1, N=55
: 16k=1, N=99
: 20k=1, N=10000
: 4001k=1, N=21345
: 18821k=2, N=10
: 1k=2, N=100
: 20k=2, N=1000
: 300k=2, N=2000
: 601k=2, N=2145
: 781k=2, N=3000
: 1900