本文使用python实现
1. 问题
求1~1300的整数中1出现的次数?比如1,10,11,12,13这5个数字中1出现了6次。
时间限制:1s;空间限制:32768K
2 思路描述
方法一:暴力解法(当数字较小时可以,数字很大时不可取)
方法二:观察规律(在此我们将题目拓展成整数中 X 出现的次数, X∈{1,2,3,4,5,6,7,8,9} )
(1)在 [1,10] 中 ,个位上 X 出现的次数为 1 。
(2)在 [11,100] 中,十位上 X 出现的次数为 10 。
(3)在 [101,1000] 中,百位上 X 出现的次数为 100 。
(4)以此类推,在 [10i+1,10(i+1)] 上,从右数第 i 位上 X 出现的次数为 10(i−1) 。
而 [1,n] 中第 i 位上 X 出现的次数规律为:
(a)当第 i 位的数字 >X 时,[1,n] 中第 i 位上为 X 的个数为:(n//10i+1)∗10(i−1)
(b)当第 i 位的数字 <X 时,[1,n] 中第 i 位上为 X 的个数为:(n//10i)∗10(i−1)
(c)当第 i 位的数字 =X 时,[1,n] 中第 i 位上为 X 的个数为:(n//10i)∗10(i−1)+(n取模10i−1∗10(i−1)+1)
注意:// 表示整除的意思。
举例说明:
对于 [1,2593] 中 5 出现的次数:
(1)个位(从右至左第1位):由于个位 3<5 ,故对照规律(b):2593//101×10(1−0)=259 ,也就是说,在 [0 2593] 中 5 在个位上出现了 259 次。
(2)十位(从右至左第2位):由于十位上的数字 9>5 ,故对照规律(a): (2593//102+1)×10(2−1)=260 ,也就是说,在 [0 2593] 中 5 在十位上出现了 260 次。
(3)百位(从右至左第3位):由于百位上的数字 5=5 ,故对照规律(c): (2593//103)∗10(3−1)+(2593取模103−5∗10(3−1)+1)=294 ,也就是说,在 [0 2593] 中 5 在百位上出现了 294 次。
(4)千位(从右至左第4位):由于百千位上的数字 2<5 ,故对照规律(b):(2593//104)×10(4−0)=0 ,也就是说,在 [0 2593] 中 5 在千位上出现了 0 次。
故 5 在 [1,2593] 中共出现了 259+260+294+0=813 次。
3 程序代码:
class Solution:
def NumberOf1Between1AndN_Solution(self, n):
count = 0
tmp = n
i = 1
while tmp != 0:
# a为每位上的数字
a = tmp % 10
rem = n % (10**i)
con = n // (10**i)
base = 10**(i-1)
if a > 1:
count += (con + 1) * base
elif a < 1:
count += con * base
else:
count += con * base + (rem - 1*base + 1)
tmp = tmp // 10
i += 1
return count