求从1到n的正整数中1出现的次数

博客探讨了如何高效地计算从1到n的正整数中1出现的次数,通过分析规律提出递归函数,指出遍历方法在面试中可能不被接受,并对比了循环与递归的时间复杂度。
摘要由CSDN通过智能技术生成

题目:输入一个数字n,求从1到n的正整数出现的次数。

例如:输入13,则包含1的数字有 1 10 11 12 13 这5个数,但是1出现的次数为6次。再比如输入29,则1出现1 10-19 21 这些数字,1共出现可知为13个。

本题目据说是google的一到面试题,刚开始思路有了,到最后完整实现用了一定时间。

最容易想到的方法:遍历,将所有1到n的数字都拿来遍历一边,计数1出现的次数。如果在面试的时候,采用此方法,肯定会被pass掉的。

接下来就是寻找规律,可以发现个位数里面只有1 出现1, 十位数中中内10-19这几个数字都有1,但是其他的20-29,30-39,,,90-99每个里面只有1个1。所有十位数中1出现的总和是20个。可以知道十位数的个位上出现10次,十位上出现10次。于是所有N位数出现1的个数可以通过如下递归函数得到。

def funit(width):
    if width == 1:
        return 1
    else:
        return 10 ** (width - 1) + 10 * funit(width -1)

从上面的函数计算可以funit(1) =1 , funit(2)=20, funit(3)=300,这些数字都是对应所有的位数,相当于9,99,999内1的个数为1 20 300。

如果我们那654举例子,百位上肯定会出现10^2共100此,十位上会出现10^1 + 6*funit(2)共计6*20+10=130次,个位上出现10^0+5*fu

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值