Skip to content

Commit a075b78

Browse files
committed
New Problem Solution "Nth Digit"
1 parent 02fd2b7 commit a075b78

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LeetCode
88

99
| # | Title | Solution | Difficulty |
1010
|---| ----- | -------- | ---------- |
11+
|400|[Nth Digit](https://leetcode.com/problems/nth-digit/) | [C++](./algorithms/cpp/nthDigit/NthDigit.cpp)|Easy|
1112
|399|[Evaluate Division](https://leetcode.com/problems/evaluate-division/) | [C++](./algorithms/cpp/evaluateDivision/EvaluateDivision.cpp)|Medium|
1213
|398|[Random Pick Index](https://leetcode.com/problems/random-pick-index/) | [C++](./algorithms/cpp/randomPickIndex/RandomPickIndex.cpp)|Medium|
1314
|397|[Integer Replacement](https://leetcode.com/problems/integer-replacement/) | [C++](./algorithms/cpp/integerReplacement/IntegerReplacement.cpp)|Medium|

algorithms/cpp/nthDigit/NthDigit.cpp

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Source : https://leetcode.com/problems/nth-digit/
2+
// Author : Hao Chen
3+
// Date : 2016-11-05
4+
5+
/***************************************************************************************
6+
*
7+
* Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
8+
* 11, ...
9+
*
10+
* Note:
11+
* n is positive and will fit within the range of a 32-bit signed integer (n 31).
12+
*
13+
* Example 1:
14+
*
15+
* Input:
16+
* 3
17+
*
18+
* Output:
19+
* 3
20+
*
21+
* Example 2:
22+
*
23+
* Input:
24+
* 11
25+
*
26+
* Output:
27+
* 0
28+
*
29+
* Explanation:
30+
* The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which
31+
* is part of the number 10.
32+
***************************************************************************************/
33+
34+
35+
#include <cmath>
36+
using namespace std;
37+
38+
class Solution {
39+
public:
40+
int findNthDigit(int n) {
41+
42+
// We can see the following pattern:
43+
//
44+
// 1, 2, .... 9 : there are 9 * 1 digits.
45+
// 10, 11, ..., 99: there are 90 * 2 digits.
46+
// 101, 102, 103, ..., 999: there are 900 * 3.
47+
// ...
48+
49+
50+
//we can count the digits with the above pattern
51+
long digits_cnt = 0;
52+
long digits_cnt_prev = 0;
53+
int base = 0;
54+
for ( ; digits_cnt < n; base++) {
55+
digits_cnt_prev = digits_cnt;
56+
digits_cnt = digits_cnt + 9 * pow(10 , base) * ( base + 1 );
57+
}
58+
59+
60+
// Now, we got `digits_cnt_prev`, `digits_cnt` and `base`
61+
//
62+
// For examples:
63+
// n = 20; digits_cnt_prev = 9, digits_cnt = 9+90*2 = 189, base = 2;
64+
// n = 500; digits_cnt_prev = 9+90*2 = 189, digits_cnt = 9+90*2+900*3 = 2889, base = 3;
65+
// n = 2000; digits_cnt_prev = 9+90*2 = 189, digits_cnt = 9+90*2+900*3 = 2889, base = 3;
66+
//
67+
// It means, we found the range where the number it is
68+
// n = 20, the number located in the range 10 -- 99
69+
// n = 500, the number located in the range 100 - 999
70+
//
71+
// and we can use `digits_cnt_prev` to know the previous rangs produce how many digits.
72+
// n = 20, the previous ranges produce 9 digits, so there needs 20-9 = 11 digits in [10 - 99]
73+
// n = 500, the previous ranges produce 189 digits, so there needs 500-189 = 311 digits in [100-999]
74+
//
75+
// the `base` told us in current ranges, each number can have how many digits.
76+
// then we can locate the target number.
77+
// n = 20,
78+
// (n - digits_cnt_prev) / base = (20 - 9 ) / 2 = 5, so, [10 - 14] produces 10 digits (ZERO-based),
79+
// now, we have 1 digits left, it is the first digit of the target number 15.
80+
//
81+
// n = 500,
82+
// (n - digits_cnt_prev) / base = (500 - 189) / 3 = 103, so, [100 - 202] produces 309 digits(ZERO-based).
83+
// now, we have (500 - 189 - 309) = 2 digits left, it is the second digit of the target number 203.
84+
//
85+
// We can write the code now...
86+
//
87+
int target = pow(10, base-1) + (n - digits_cnt_prev) / base - 1;
88+
int left = n - digits_cnt_prev - (n - digits_cnt_prev) / base * base;
89+
90+
//cout << "target = " << target << ", left = " << left << endl;
91+
92+
//no digits left
93+
if ( left == 0 ) return (target) % 10;
94+
95+
//still have some digits left, it should be in next number.
96+
target++;
97+
return int( target / pow(10, base - left) ) % 10;
98+
}
99+
};

0 commit comments

Comments
 (0)