233. Number of Digit One 详细解答
2017-07-31 20:29
141 查看
Approach #1 Brute force [Time Limit Exceeded]
IntuitionDo as directed in question.
Algorithm
Iterate over ii from 11 to nn:
Convert ii to
string and count \text{'1'}’1’ in
each integer string
Add count of \text{'1'}’1’ in
each string to the sum, say countrcountr
C++
int countDigitOne(int n) { int countr = 0; for (int i = 1; i <= n; i++) { string str = to_string(i); countr += count(str.begin(), str.end(), '1'); } return countr; }
Complexity Analysis
Time complexity: O(n*log_{10}(n))O(n∗log10(n)).
We iterate from 11 to nn
In each iteration, we convert integer to string and count '1' in string which takes linear time in number of digits in ii,
which is log_{10}(n)log10(n).
Space complexity: O(log_{10}(n))O(log10(n)) Extra
space for the countr and the converted string \text{str}str.
Approach #2 Solve it mathematically [Accepted]
IntuitionIn Approach #1, we manually calculated the number of all the '1'′1′s
in the digits, but this is very slow. Hence, we need a way to find a pattern in the way '1'′1′s
(or for that matter any digit) appears in the numbers. We could then use the pattern to formulate the answer.
Consider the 11s
in \text{ones}ones place
, \text{tens}tens place, \text{hundreds}hundreds place
and so on... An analysis has been performed in the following figure.
From the figure, we can see that from digit '1' at \text{ones}ones place
repeat in group of 1 after interval of 1010.
Similarly, '1' at \text{tens}tens place
repeat in group of 10 after interval of 100100.
This can be formulated as (n/(i*10))*i(n/(i∗10))∗i.
Also, notice that if the digit at \text{tens}tens place
is \text{'1'}’1’,
then the number of terms with \text{'1's}’1’s is
increased by x+1x+1,
if the number is say \text{"ab1x"}"ab1x".
As if digits at \text{tens}tensplace
is greater than 11,
then all the 1010 occurances
of numbers with '1'′1′ at \text{tens}tens place
have taken place, hence, we add 1010.
This is formluated as {\min(\max((\text{n
mod (i*10)} )-i+1,0),i)}min(max((n mod (i*10))−i+1,0),i).
Lets take an example, say n=
1234n=1234.
No of \text{'1'}’1’ in \text{ones}ones place
= 1234/101234/10(corresponding
to 1,11,21,...1221) + \min(4,1)min(4,1)(corresponding
to 1231) =124124
No of \text{'1'}’1’ in \text{tens}tens place
= (1234/100)*10(1234/100)∗10(corresponding
to 10,11,12,...,110,111,...1919) +\min(21,10)min(21,10)(corresponding
to 1210,1211,...1219)=130130
No of \text{'1'}’1’ in \text{hundreds}hundreds place
= (1234/1000)*100(1234/1000)∗100(corresponding
to 100,101,12,...,199) +\min(135,100)min(135,100)(corresponding
to 1100,1101...1199)=200200
No of \text{'1'}’1’ in \text{thousands}thousands place
= (1234/10000)*10000(1234/10000)∗10000 +\min(235,1000)min(235,1000)(corresponding
to 1000,1001,...1234)=235235
Therefore, Total = 124+130+200+235
= 689124+130+200+235=689.
Herein, one formula has been devised, but many other formulae can be devised for faster implementations, but the essence and complexity remains the same. The users are encouraged to try to divise their own version of solution using the mathematical concepts.
Algorithm
Iterate over ii from 11 to nn incrementing
by 1010 each
time:
Add (n/(i*10))*i(n/(i∗10))∗i to \text{countr}countr representing
the repetition of groups of $$i$ sizes after each (i*10)(i∗10) interval.
Add {\min(\max((\text{n
mod (i*10)} )-i+1,0),i)}min(max((n mod (i*10))−i+1,0),i) to \text{countr}countr representing
the additional digits dependant on the digit in iith
place as described in intuition.
C++
int countDigitOne(int n) { int countr = 0; for (long long i = 1; i <= n; i *= 10) { long long divider = i * 10; countr += (n / divider) * i + min(max(n % divider - i + 1, 0LL), i); } return countr; }
Complexity analysis
Time complexity: O(log_{10}(n))O(log10(n)).
No of iterations equal to the number of digits in n which is log_{10}(n)log10(n)
Space complexity: O(1)O(1) space
required.
相关文章推荐
- 233. Number of Digit One
- 233. Number of Digit One
- [leetcode]233. Number of Digit One
- [leetcode]233. Number of Digit One
- 233. Number of Digit One
- leetcode 233. Number of Digit One 从1到n的数组中出现数字1的数量 + 寻找规律,公式计算
- leetcode 233. Number of Digit One
- 233. Number of Digit One【H】【33】【再来一遍】
- 233. Number of Digit One
- 233. Number of Digit One
- 233. Number of Digit One
- Hard-题目26:233. Number of Digit One
- [leetcode] 233. Number of Digit One 解题报告
- LeetCode Algorithms 233. Number of Digit One 题解
- 233. Number of Digit One
- leetcode hard模式专杀之233. Number of Digit One
- 233. Number of Digit One
- leetcode233. Number of Digit One
- leetcode 233. Number of Digit One
- [LeetCode]233. Number of Digit One