题目:
思路+代码:
法一:暴力法。遍历求和(超时)
class Solution:
def countDigitOne(self, n: int) -> int:
# 暴力法超时
if not n: return 0
count = 0
for k in range(1, n+1):
while k:
temp = k % 10
if temp == 1:
count += 1
k //= 10
return count
法二:找规律:
cur是当前位; high是高位; low是低位
cur = 1, res = high * digit + low + 1; 比如:digit = 10, num=23610, res = 236*10+0 + 1=2361; (1-23519)
cur >1, res = (high + 1) * digit; 比如:digit = 10, num=23623, res = (236+1)*10=2370; (1-23619)
cur = 0, res = high * digit; 比如:digit = 10, num=23603, res = 236*10=2370; (1-23519)
class Solution:
def countDigitOne(self, n: int) -> int:
# 找规律:
# cur = 1, res = high * digit + low + 1; 比如:digit = 10, num=23610, res = 236*10+0 + 1=2361; (1-23519)
# cur >1, res = (high + 1) * digit; 比如:digit = 10, num=23623, res = (236+1)*10=2370; (1-23619)
# cur = 0, res = high * digit; 比如:digit = 10, num=23603, res = 236*10=2370; (1-23519)
digit, res = 1, 0
high, cur, low = n // 10, n % 10, 0
while high != 0 or cur != 0:
if cur == 0: res +=
elif cur == 1: res += high * digit + low + 1
else: res += (high + 1) * digit
low += cur * digit
cur = high % 10
high //= 10
digit *= 10
return res
时间复杂度:O(logn)
空间复杂度:O(1)