Skip to content

Commit 46287a0

Browse files
committed
feat: add solutions to lc/lcof problems
* lc No.0400 & lcof No.44.Nth Dight
1 parent 8d7e2ff commit 46287a0

File tree

18 files changed

+387
-259
lines changed

18 files changed

+387
-259
lines changed

lcof/面试题44. 数字序列中某一位的数字/README.md

Lines changed: 75 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,17 @@
3535

3636
<!-- 这里可写通用的实现逻辑 -->
3737

38-
- pow = 0:0~9 有 10 位
39-
- pow = 1: 10~99 有 `90*2=180`
40-
- pow = 2: 100~999 有 `900*3=2700` 位。
38+
**方法一:数学**
4139

42-
先求出第 n 位所在的 pow 和真实数字,进而求出真实数字的第 `n % (pow + 1)` 位即可。
40+
位数为 $k$ 的最小整数和最大整数分别为 $10^{k-1}$ 和 $10^k-1$,因此 $k$ 位数的总位数为 $k \times 9 \times 10^{k-1}$。
41+
42+
我们用 $k$ 表示当前数字的位数,用 $cnt$ 表示当前位数的数字的总数,初始时 $k=1$, $cnt=9$。
43+
44+
每次将 $n$ 减去 $cnt \times k$,当 $n$ 小于等于 $cnt \times k$ 时,说明 $n$ 对应的数字在当前位数的数字范围内,此时可以计算出对应的数字。
45+
46+
具体做法是,首先计算出 $n$ 对应的是当前位数的哪一个数字,然后计算出是该数字的第几位,从而得到该位上的数字。
47+
48+
时间复杂度 $O(\log_{10} n)$。
4349

4450
<!-- tabs:start -->
4551

@@ -50,20 +56,14 @@
5056
```python
5157
class Solution:
5258
def findNthDigit(self, n: int) -> int:
53-
def get_bit_num():
54-
return 10 if p == 0 else 9 * pow(10, p) * (p + 1)
55-
56-
if n < 10:
57-
return n
58-
p = count = 0
59-
while 1:
60-
count = get_bit_num()
61-
if n < count:
62-
break
63-
n -= count
64-
p += 1
65-
num = n // (p + 1) + pow(10, p)
66-
return int(str(num)[n % (p + 1)])
59+
k, cnt = 1, 9
60+
while k * cnt < n:
61+
n -= k * cnt
62+
k += 1
63+
cnt *= 10
64+
num = 10 ** (k - 1) + (n - 1) // k
65+
idx = (n - 1) % k
66+
return int(str(num)[idx])
6767
```
6868

6969
### **Java**
@@ -73,24 +73,51 @@ class Solution:
7373
```java
7474
class Solution {
7575
public int findNthDigit(int n) {
76-
if (n < 10) return n;
77-
int pow = 0, count;
78-
while (true) {
79-
count = getBitNum(pow);
80-
if (n < count) break;
81-
n -= count;
82-
++pow;
76+
int k = 1, cnt = 9;
77+
while ((long) k * cnt < n) {
78+
n -= k * cnt;
79+
++k;
80+
cnt *= 10;
8381
}
84-
int num = n / (pow + 1) + (int) Math.pow(10, pow);
85-
return String.valueOf(num).charAt(n % (pow + 1)) - '0';
82+
int num = (int) Math.pow(10, k - 1) + (n - 1) / k;
83+
int idx = (n - 1) % k;
84+
return String.valueOf(num).charAt(idx) - '0';
8685
}
86+
}
87+
```
88+
89+
### **C++**
8790

88-
private int getBitNum(int pow) {
89-
if (pow == 0) {
90-
return 10;
91+
```cpp
92+
class Solution {
93+
public:
94+
int findNthDigit(int n) {
95+
int k = 1, cnt = 9;
96+
while (1ll * k * cnt < n) {
97+
n -= k * cnt;
98+
++k;
99+
cnt *= 10;
91100
}
92-
return (int) (9 * Math.pow(10, pow) * (pow + 1));
101+
int num = pow(10, k - 1) + (n - 1) / k;
102+
int idx = (n - 1) % k;
103+
return to_string(num)[idx] - '0';
93104
}
105+
};
106+
```
107+
108+
### **Go**
109+
110+
```go
111+
func findNthDigit(n int) int {
112+
k, cnt := 1, 9
113+
for k*cnt < n {
114+
n -= k * cnt
115+
k++
116+
cnt *= 10
117+
}
118+
num := int(math.Pow10(k-1)) + (n-1)/k
119+
idx := (n - 1) % k
120+
return int(strconv.Itoa(num)[idx] - '0')
94121
}
95122
```
96123

@@ -102,42 +129,16 @@ class Solution {
102129
* @return {number}
103130
*/
104131
var findNthDigit = function (n) {
105-
let i = 9;
106-
let a = 1;
107-
let remain = n;
108-
while (i * a < remain) {
109-
remain -= i * a;
110-
i *= 10;
111-
a++;
112-
}
113-
let b = remain % a;
114-
let res = 10 ** (a - 1) + ~~(remain / a);
115-
if (b === 0) {
116-
b = a;
117-
res--;
118-
}
119-
return res.toString()[b - 1];
120-
};
121-
```
122-
123-
### **C++**
124-
125-
```cpp
126-
class Solution {
127-
public:
128-
int findNthDigit(int n) {
129-
int digit = 1;
130-
long long start = 0;
131-
long long count = 10;
132-
while (n > count) {
133-
n -= count;
134-
++digit;
135-
start = start == 0 ? 10 : start * 10;
136-
count = 9 * start * digit;
137-
}
138-
long long num = start + n / digit;
139-
return to_string(num)[n % digit] - '0';
132+
let k = 1,
133+
cnt = 9;
134+
while (k * cnt < n) {
135+
n -= k * cnt;
136+
++k;
137+
cnt *= 10;
140138
}
139+
const num = Math.pow(10, k - 1) + (n - 1) / k;
140+
const idx = (n - 1) % k;
141+
return num.toString()[idx];
141142
};
142143
```
143144

@@ -146,32 +147,17 @@ public:
146147
```cs
147148
public class Solution {
148149
public int FindNthDigit(int n) {
149-
long length = 1;
150-
long count = 10;
151-
long tenBase = 9;
152-
long lastCount = 0;
153-
154-
while (count < n)
155-
{
156-
length++;
157-
tenBase *= 10;
158-
var currentCount = tenBase * length;
159-
lastCount = count;
160-
count += currentCount;
150+
int k = 1, cnt = 9;
151+
while ((long) k * cnt < n) {
152+
n -= k * cnt;
153+
++k;
154+
cnt *= 10;
161155
}
162-
163-
var remainder = n - lastCount;
164-
var value = remainder / length;
165-
if (length > 1)
166-
{
167-
value += (int)Math.Pow(10, length - 1);
168-
}
169-
170-
remainder %= length;
171-
return value.ToString()[(int)remainder] - '0';
156+
int num = (int) Math.Pow(10, k - 1) + (n - 1) / k;
157+
int idx = (n - 1) % k;
158+
return num.ToString()[idx] - '0';
172159
}
173160
}
174-
175161
```
176162

177163
### **...**
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
class Solution {
22
public:
33
int findNthDigit(int n) {
4-
int digit = 1;
5-
long long start = 0;
6-
long long count = 10;
7-
while (n > count) {
8-
n -= count;
9-
++digit;
10-
start = start == 0 ? 10 : start * 10;
11-
count = 9 * start * digit;
4+
int k = 1, cnt = 9;
5+
while (1ll * k * cnt < n) {
6+
n -= k * cnt;
7+
++k;
8+
cnt *= 10;
129
}
13-
long long num = start + n / digit;
14-
return to_string(num)[n % digit] - '0';
10+
int num = pow(10, k - 1) + (n - 1) / k;
11+
int idx = (n - 1) % k;
12+
return to_string(num)[idx] - '0';
1513
}
16-
};
14+
};
Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,13 @@
11
public class Solution {
22
public int FindNthDigit(int n) {
3-
long length = 1;
4-
long count = 10;
5-
long tenBase = 9;
6-
long lastCount = 0;
7-
8-
while (count < n)
9-
{
10-
length++;
11-
tenBase *= 10;
12-
var currentCount = tenBase * length;
13-
lastCount = count;
14-
count += currentCount;
3+
int k = 1, cnt = 9;
4+
while ((long) k * cnt < n) {
5+
n -= k * cnt;
6+
++k;
7+
cnt *= 10;
158
}
16-
17-
var remainder = n - lastCount;
18-
var value = remainder / length;
19-
if (length > 1)
20-
{
21-
value += (int)Math.Pow(10, length - 1);
22-
}
23-
24-
remainder %= length;
25-
return value.ToString()[(int)remainder] - '0';
9+
int num = (int) Math.Pow(10, k - 1) + (n - 1) / k;
10+
int idx = (n - 1) % k;
11+
return num.ToString()[idx] - '0';
2612
}
27-
}
13+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
func findNthDigit(n int) int {
2+
k, cnt := 1, 9
3+
for k*cnt < n {
4+
n -= k * cnt
5+
k++
6+
cnt *= 10
7+
}
8+
num := int(math.Pow10(k-1)) + (n-1)/k
9+
idx := (n - 1) % k
10+
return int(strconv.Itoa(num)[idx] - '0')
11+
}
Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
11
class Solution {
22
public int findNthDigit(int n) {
3-
if (n < 10) return n;
4-
int pow = 0, count;
5-
while (true) {
6-
count = getBitNum(pow);
7-
if (n < count) break;
8-
n -= count;
9-
++pow;
3+
int k = 1, cnt = 9;
4+
while ((long) k * cnt < n) {
5+
n -= k * cnt;
6+
++k;
7+
cnt *= 10;
108
}
11-
int num = n / (pow + 1) + (int) Math.pow(10, pow);
12-
return String.valueOf(num).charAt(n % (pow + 1)) - '0';
13-
}
14-
15-
private int getBitNum(int pow) {
16-
if (pow == 0) {
17-
return 10;
18-
}
19-
return (int) (9 * Math.pow(10, pow) * (pow + 1));
9+
int num = (int) Math.pow(10, k - 1) + (n - 1) / k;
10+
int idx = (n - 1) % k;
11+
return String.valueOf(num).charAt(idx) - '0';
2012
}
2113
}

lcof/面试题44. 数字序列中某一位的数字/Solution.js

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,14 @@
33
* @return {number}
44
*/
55
var findNthDigit = function (n) {
6-
let i = 9;
7-
let a = 1;
8-
let remain = n;
9-
while (i * a < remain) {
10-
remain -= i * a;
11-
i *= 10;
12-
a++;
6+
let k = 1,
7+
cnt = 9;
8+
while (k * cnt < n) {
9+
n -= k * cnt;
10+
++k;
11+
cnt *= 10;
1312
}
14-
let b = remain % a;
15-
let res = 10 ** (a - 1) + ~~(remain / a);
16-
if (b === 0) {
17-
b = a;
18-
res--;
19-
}
20-
return res.toString()[b - 1];
13+
const num = Math.pow(10, k - 1) + (n - 1) / k;
14+
const idx = (n - 1) % k;
15+
return num.toString()[idx];
2116
};
Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
class Solution:
22
def findNthDigit(self, n: int) -> int:
3-
def get_bit_num():
4-
return 10 if p == 0 else 9 * pow(10, p) * (p + 1)
5-
6-
if n < 10:
7-
return n
8-
p = count = 0
9-
while 1:
10-
count = get_bit_num()
11-
if n < count:
12-
break
13-
n -= count
14-
p += 1
15-
num = n // (p + 1) + pow(10, p)
16-
return int(str(num)[n % (p + 1)])
3+
k, cnt = 1, 9
4+
while k * cnt < n:
5+
n -= k * cnt
6+
k += 1
7+
cnt *= 10
8+
num = 10 ** (k - 1) + (n - 1) // k
9+
idx = (n - 1) % k
10+
return int(str(num)[idx])

0 commit comments

Comments
 (0)