Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.
For example:
Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
因此,应该使用算术方法来解决该问题。
Intuition
我们尝试着找到数字 1 出现的模式。考虑 1 出现在个位、十位、百位......上的情况,得到如下图的分析。
从图中,我们可以看到,个位上的数字 1 每隔 10 个数出现一次,十位上的数字 1 每隔 100 个数出现一次......这个可以用公式 (n/(i*10))*i 来表达。
除此之外,如果 n 在十位上的数字是 1 ,即"ab1x", 那么增加的数字个数为 。如果 n 在十位上的数字大于 1 ,那么所有在十位上为 1 的10个数字都会出现,那么可以增加 ,这个可以用公式 来表示。
if n = xyzdabc
如果我们考虑千位上 1 的出现次数,应该是:
(1) xyz * 1000 if d == 0
(2) xyz * 1000 + abc + 1 if d == 1
(3) xyz * 1000 + 1000 if d > 1
因此我们可以从最低位到最高位来遍历 n 中的所有数字,得到结果
public int countDigitOne(int n) { if (n <= 0) return 0; int q = n, x = 1, ans = 0; do { int digit = q % 10; q /= 10; ans += q * x; if (digit == 1) ans += n % x + 1; if (digit > 1) ans += x; x *= 10; } while (q > 0); return ans; }
举个例子,如果
’1’ 在个位上的出现次数 = (如 1,11,21,...1221) + 1 (加上 1231) =
’1’ 在十位上的出现次数 = (如 10,11,12,...,110,111,...1919) + 10 (加上 1210,1211,...1219) =
’1’ 在百位上的出现次数 = (1234/1000)∗100 (如 100,101,12,...,199) + 100 (加上 1100,1101...1199) =
’1’ 在千位上的出现次数 = + 235 (加上 1000,1001,...1234)=
所以总共 =
Complexity analysis
- Time complexity: O(log(n)).
-
No of iterations equal to the number of digits in n which is log(n)
-
Space complexity: O(1) space required.