https://leetcode.com/problems/number-of-digit-one/
想到一个优雅的解法还是不容易的

个人解答

  1. class Solution:
  2. def countDigitOne(self, n: int) -> int:
  3. e = 1
  4. res = 0
  5. origin = n
  6. while n > 0:
  7. d = n % 10
  8. n //= 10
  9. if d == 0:
  10. res += n * e
  11. elif d == 1:
  12. res += n * e + origin % e + 1
  13. else:
  14. res += n * e + e
  15. e *= 10
  16. return res

题目思路

数出所有的,那么每一位出现的次数加起来即可,这一步想明白还是要花一番功夫的。
对每一位上的数字,分三种情况讨论,整体还是比较明确的:

  1. if n = xyzdabc
  2. (1) xyz * 1000 if d == 0
  3. (2) xyz * 1000 + abc + 1 if d == 1
  4. (3) xyz * 1000 + 1000 if d > 1

编程上也要考虑一点技巧,让代码写的更简洁。

其它解法

最初写的笨笨的解法,找规律,打表,然后组合处理

  1. class Solution:
  2. def countDigitOne(self, n: int) -> int:
  3. table = {}
  4. for i in range(1, 10):
  5. table[i] = 1
  6. for i in range(1, 20):
  7. table[10 ** i] = i * 10 ** (i - 1)
  8. table[10 ** i * 2] = table[10 ** i] + 10 ** i + table[10 ** i]
  9. for j in range(3, 10):
  10. table[10 ** i * j] = table[10 ** i * (j - 1)] + table[10 ** i]
  11. res = 0
  12. s = str(n)
  13. for i, d in enumerate(s):
  14. if d == '0':
  15. continue
  16. d = int(d)
  17. e = len(s) - i - 1
  18. large = d * 10 ** e
  19. res += table[large]
  20. if d == 1 and s[i+1:]:
  21. res += int(s[i+1:]) + 1
  22. return res