233. Number of Digit One 详细解答
来源:互联网 发布:苏州软件开发公司 编辑:程序博客网 时间:2024/06/15 06:34
Approach #1 Brute force [Time Limit Exceeded]
Intuition
Do as directed in question.
Algorithm
- Iterate over i from 1 to n:
- Convert i to string and count ’1’ in each integer string
- Add count of ’1’ in each string to the sum, say countr
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∗log10(n)).
- We iterate from 1 to n
In each iteration, we convert integer to string and count '1' in string which takes linear time in number of digits in i, which is log10(n).
Space complexity: O(log10(n)) Extra space for the countr and the converted string str.
Approach #2 Solve it mathematically [Accepted]
Intuition
In Approach #1, we manually calculated the number of all the ′1′s in the digits, but this is very slow. Hence, we need a way to find a pattern in the way ′1′s (or for that matter any digit) appears in the numbers. We could then use the pattern to formulate the answer.
Consider the 1s in ones place , tens place, 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 ones place repeat in group of 1 after interval of 10. Similarly, '1' at tens place repeat in group of 10 after interval of 100. This can be formulated as (n/(i∗10))∗i.
Also, notice that if the digit at tens place is ’1’, then the number of terms with ’1’s is increased by x+1, if the number is say "ab1x". As if digits at tensplace is greater than 1, then all the 10 occurances of numbers with ′1′ at tens place have taken place, hence, we add 10. This is formluated as min(max((n mod (i*10))−i+1,0),i).
Lets take an example, say n=1234.
No of ’1’ in ones place = 1234/10(corresponding to 1,11,21,...1221) + min(4,1)(corresponding to 1231) =124
No of ’1’ in tens place = (1234/100)∗10(corresponding to 10,11,12,...,110,111,...1919) +min(21,10)(corresponding to 1210,1211,...1219)=130
No of ’1’ in hundreds place = (1234/1000)∗100(corresponding to 100,101,12,...,199) +min(135,100)(corresponding to 1100,1101...1199)=200
No of ’1’ in thousands place = (1234/10000)∗10000 +min(235,1000)(corresponding to 1000,1001,...1234)=235
Therefore, Total = 124+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 i from 1 to n incrementing by 10 each time:
- Add (n/(i∗10))∗i to countr representing the repetition of groups of $$i$ sizes after each (i∗10) interval.
- Add min(max((n mod (i*10))−i+1,0),i) to countr representing the additional digits dependant on the digit in ith 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(log10(n)).
No of iterations equal to the number of digits in n which is log10(n)
Space complexity: O(1) space required.
- 233. Number of Digit One 详细解答
- 233. Number of Digit One
- 233. Number of Digit One
- 233. Number of Digit One
- 233. Number of Digit One
- 233. Number of Digit One
- 233. Number of Digit One
- 233. Number of Digit One
- Number of Digit One
- Number of Digit One
- Number of Digit One
- Number of Digit One
- Number of Digit One
- Number of Digit One
- Number of Digit One
- Number of Digit One
- Number of Digit One
- Number of Digit One
- XYNUOJ 1256 喷水装置(一)—贪心算法
- 农业网
- XYNUOJ 1257 捕杀恶龙—贪心算法
- C++填坑之路
- C语言——实例041 static 静态局部变量
- 233. Number of Digit One 详细解答
- WPF中ListBox的item中有Button或其他控件时点击事件的处理
- 什么是跨域?如何解决跨域问题?
- 开灯问题
- 17暑假多校联赛1.1 HDU 6033 Add More Zero
- 关于chrome上的网银安全控件开发技术(chrome 调用本地dll)
- jsp:useBean出现中文乱码
- Spring 的 IOC 容器和SpringMVC 的IOC容器
- XYNUOJ 1259 找零钱—贪心算法