Algorithm 计算0和N之间的Ks数 问题:
我见过这样的问题:Algorithm 计算0和N之间的Ks数 问题:,algorithm,numbers,range,time-complexity,counting,Algorithm,Numbers,Range,Time Complexity,Counting,我见过这样的问题: 这类问题非常类似于要求查找在数字范围[0,N]中显示的Ks(即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包含两个2s) 我们所拥有的: 每个问题都有解决方案(如果您搜索,可以使用)。通常,O(logn)通过递归地考虑最高数字来解决此类问题需要时间,以此类推。计算0和N之间的2的数量的一
[0,N]
中显示的Ks(即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
s)2
我们所拥有的: 每个问题都有解决方案(如果您搜索,可以使用)。通常,
O(logn)
通过递归地考虑最高数字来解决此类问题需要时间,以此类推。计算0和N之间的2的数量的一个示例可以通过以下步骤解决(借用自):
测试用例: 如果您想检查解决方案,以下是一些测试用例:
:1k=1,N=1
:1k=1,N=5
:2k=1,N=10
:16k=1,N=55
:20k=1,N=99
:4001k=1,N=10000
:18821k=1,N=21345
:1k=2,N=10
:20k=2,N=100
:300k=2,N=1000
:601k=2,N=2000
:781k=2,N=2145
:1900k=2,N=3000
请记住,第一个数字so也可能包含所需的值。对于情况0,我们需要单独处理 对于1到9的一般情况: 假设我们知道数字包含有x位数的k,并称之为m,要计算所有包含k且有(x+1)位数的数字,公式如下:
9*m + (all_number_has_x_digit - m)
原因很简单,对于所有已经包含k的数字,我们可以插入1到9作为第一个数字,所以我们有9*m。对于不包含k的所有数字,我们可以在它们前面添加k,这就创建了所有数字(数字为x,数字为-m)
要计算从所有这些数字中出现的k的数量,公式应该是相似的(通过保持两个值:包含k的数字的数量和k的出现数量),这只是一个开始的想法:)可以通过算术完成 编辑 起初我没有看到您的代码示例。我的代码非常相似,只是输入是参数化的。所以答案是肯定的,它可以推广,但是你需要把0作为特例来处理 如果给定的数字N是两位数,我们假设AB,我们计算的是数字K(1..9) 您的示例输入:K=2,N=35
5 is greater than 2 -> count = 1 (this is digit 2 in number 32)
3 is greater than 2 -> count += 3 (this are twos in 2, 12, 22) + 10 (this are 20,21,22,23,24,25,26,27,28,29)
*22 is counted twice
所以我们计算1+3+10=14个2
C代码示例(n=1..99,k=1..9):
更新2
因为k=0(包括0和n)更容易,所以只需要计算可被10、100、1000等整除的数字
int numberOf0sBetween0AndN(int n)
{
int power = 1;
int counter = 1;
while(power < n)
{
power *= 10;
counter += n / power;
}
return counter;
}
0和n之间的0的整数(整数n)
{
整数幂=1;
int计数器=1;
while(功率
我相信这正是您需要的,简单、通用、快速
下面是Python中的一个示例:
慢检查器
检查程序很简单,使用string
查找字符串中从“0”-“n”开始的所有数字,并计算k
的匹配时间,速度很慢,但我们可以使用它检查其他解决方案
import string
def knChecker( k, n ):
ct = 0
k = str(k)
for i in xrange(0,n+1):
ct += string.count(str(i),k)
return ct
快速通解
K≠ 0
对于每个k=[1,9],很明显在[0,9]中我们可以在第一位找到1个匹配项
在[0,99]中,我们可以在第一位找到1个匹配项,在第二位找到10个匹配项,所以都是1*10^1+10*10^0=20个匹配项
在[0999]中,我们可以在第一位找到1个匹配项,在第二位找到10个匹配项,在第三位找到100个匹配项,所以所有匹配项都是1*10^2+10*10^1+100*10^0=300个匹配项
因此我们很容易得出结论,在[0,10^l-1]中,存在l*10^(l-1)
匹配
更一般地说,我们可以在[0,f*10^l-1]中找到f*10^(l-1)*l
匹配项
因此,解决方案如下:
例如,n='abcd',k='k'
- 步骤1:如果n=0或n='',则返回0;计数“a000”中的匹配项,使用向上公式,l=len(n)
- 步骤2a:如果a==k,我们知道所有的“bcd”都匹配,所以添加
matchesbcd
- 步骤2b:如果a>k,我们知道所有的“k***”都匹配,所以添加
matches10^(l-1)
- 步骤3:剪切第一位a,并设置n=‘bcd’,转到步骤1
def knSolver( k, n ):
if k == '0':
return knSolver0( n, 0 )
if not n:
return 0
ct = 0
n = int(n)
k = int(k)
l = len(str(n))
f = int(str(n)[:1])
if l > 1:
ct += f * 10 ** (l-2) * (l-1)
if f > k:
ct += 10 ** (l-1)
elif f == k:
ct += n - f * 10 ** (l-1) + 1
return ct + knSolver( k, str(n)[1:])
k=0
k=0有点棘手,因为0***
等于***
,并且不允许对其进行计数,因为它是“0”
那么k的解呢≠ 0不能适应k=0。但想法是相似的
我们可以发现,如果n<100,则必须有n/10+1
匹配项
如果n在[100199]中,它与k非常相似≠ [0,99]中的0有20个匹配项
如果[100999]中有n,则与k非常相似≠ [100999]中的0,有20*9个匹配项
如果n在[10009999]中,它与k非常相似≠ [10009999]中的0有300*9个匹配项
更一般地说,如果n在[10^l,k*10^l-1]中,它将具有l*10^(l-1)*k
匹配项
因此,解决方案如下:
例如,n='abcd',k='0',递归步骤s
=0
- 步骤0:如果n='',则返回0;如果n<100,则返回
李>n/10+1
- 步骤1a:n='f(…)'
int numberOfKsBetween0AndN (int n, int k) { int power = 1; int counter = 0; while (n > 0) { int d = n % 10; n /= 10; counter += (d < k ? 0 : power) + d * power / 10; power *= 10; } return counter; }
int numberOfKsBetween0AndN (int n, int k) { int originalNumber = n; int power = 1; int i = 0; int counter = 0; while (n > 0) { int d = n % 10; n /= 10; counter += d * (power * i) / 10; if (d > k) counter += power; else if (d == k) counter += originalNumber % power + 1; power *= 10; i++; } return counter; }
int numberOf0sBetween0AndN(int n) { int power = 1; int counter = 1; while(power < n) { power *= 10; counter += n / power; } return counter; }
import string def knChecker( k, n ): ct = 0 k = str(k) for i in xrange(0,n+1): ct += string.count(str(i),k) return ct
def knSolver( k, n ): if k == '0': return knSolver0( n, 0 ) if not n: return 0 ct = 0 n = int(n) k = int(k) l = len(str(n)) f = int(str(n)[:1]) if l > 1: ct += f * 10 ** (l-2) * (l-1) if f > k: ct += 10 ** (l-1) elif f == k: ct += n - f * 10 ** (l-1) + 1 return ct + knSolver( k, str(n)[1:])
def knSolver0( n, s ): if n == '': return 0 ct = 0 sn = str(n) l = len(sn) f = int(sn[:1]) n = int(n) if n < 100 and s == 0: return n / 10 + 1 if s > 0 and f > 0: ct += 10 ** (l-1) + (l-1) * 10 ** (l-2) elif s > 0 and f == 0: ct += n + 1 if n >= 100 and s == 0: ct += 10 for i in xrange(2,l): if i == l-1: ct += i * 10 ** (i-1) * (f-1) else: ct += i * 10 ** (i-1) * 9 elif s > 0 and f != 0: ct += (f-1) * 10 ** (l-2) * (l-1) return int(ct + knSolver0( sn[1:], s+1 ))
print "begin check..." for k in xrange(0,10): sk = str(k) for i in xrange(0,10000): #knSolver( sk, i ) if knChecker( sk, i ) != knSolver( sk, i ): print i, knChecker( sk, i ) , knSolver( sk, i ) print "check end!"
//_k --> pattern //_n range Regex r = new Regex(_k.ToString(), RegexOptions.IgnoreCase); int count = 0; for (int i = 0; i <= _n; i++) { MatchCollection m = r.Matches(i.ToString()); foreach(Match _m in m) { if (_m.Success) { count += 1; } } } Console.WriteLine(count);