Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit da3ed3d

Browse files
feat: add solutions to lc problem: No.0788 (doocs#3543)
No.0788.Rotated Digits
1 parent d28b39b commit da3ed3d

File tree

9 files changed

+475
-351
lines changed

9 files changed

+475
-351
lines changed

‎solution/0700-0799/0788.Rotated Digits/README.md‎

Lines changed: 149 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ tags:
2929

3030
<pre><strong>输入:</strong> 10
3131
<strong>输出:</strong> 4
32-
<strong>解释:</strong>
32+
<strong>解释:</strong>
3333
在[1, 10]中有四个好数: 2, 5, 6, 9。
3434
注意 1 和 10 不是好数, 因为他们在旋转之后不变。
3535
</pre>
@@ -56,9 +56,9 @@ tags:
5656

5757
我们先用一个长度为 10ドル$ 的数组 $d$ 记录每个有效数字对应的旋转数字,在这道题中,有效数字有 $[0, 1, 8, 2, 5, 6, 9],ドル分别对应旋转数字 $[0, 1, 8, 5, 2, 9, 6]$。如果不是有效数字,我们将对应的旋转数字设为 $-1$。
5858

59-
然后遍历数字 $x$ 的每一位数字 $v,ドル如果 $v$ 不是有效数字,说明 $x$ 不是好数,直接返回 `false`。否则,我们将数字 $v$ 对应的旋转数字 $d[v]$ 加入到 $y$ 中。最后,判断 $x$ 和 $y$ 是否相等,若不相等,则说明 $x$ 是好数,返回 `true`
59+
然后遍历数字 $x$ 的每一位数字 $v,ドル如果 $v$ 不是有效数字,说明 $x$ 不是好数,直接返回 $\textit{false}$。否则,我们将数字 $v$ 对应的旋转数字 $d[v]$ 加入到 $y$ 中。最后,判断 $x$ 和 $y$ 是否相等,若不相等,则说明 $x$ 是好数,返回 $\textit{true}$
6060

61-
时间复杂度 $O(n\times \log n)$。
61+
时间复杂度 $O(n\times \log n),ドル其中 $n$ 为题目给定的数字。空间复杂度 $O(1)$。
6262

6363
相似题目:
6464

@@ -125,30 +125,28 @@ class Solution {
125125
```cpp
126126
class Solution {
127127
public:
128-
const vector<int> d = {0, 1, 5, -1, -1, 2, 9, -1, 8, 6};
129-
130128
int rotatedDigits(int n) {
129+
int d[10] = {0, 1, 5, -1, -1, 2, 9, -1, 8, 6};
130+
auto check = [&](int x) -> bool {
131+
int y = 0, t = x;
132+
int k = 1;
133+
while (t) {
134+
int v = t % 10;
135+
if (d[v] == -1) {
136+
return false;
137+
}
138+
y = d[v] * k + y;
139+
k *= 10;
140+
t /= 10;
141+
}
142+
return x != y;
143+
};
131144
int ans = 0;
132145
for (int i = 1; i <= n; ++i) {
133146
ans += check(i);
134147
}
135148
return ans;
136149
}
137-
138-
bool check(int x) {
139-
int y = 0, t = x;
140-
int k = 1;
141-
while (t) {
142-
int v = t % 10;
143-
if (d[v] == -1) {
144-
return false;
145-
}
146-
y = d[v] * k + y;
147-
k *= 10;
148-
t /= 10;
149-
}
150-
return x != y;
151-
}
152150
};
153151
```
154152
@@ -180,6 +178,31 @@ func rotatedDigits(n int) int {
180178
}
181179
```
182180

181+
#### TypeScript
182+
183+
```ts
184+
function rotatedDigits(n: number): number {
185+
const d: number[] = [0, 1, 5, -1, -1, 2, 9, -1, 8, 6];
186+
const check = (x: number): boolean => {
187+
let y = 0;
188+
let t = x;
189+
let k = 1;
190+
191+
while (t > 0) {
192+
const v = t % 10;
193+
if (d[v] === -1) {
194+
return false;
195+
}
196+
y = d[v] * k + y;
197+
k *= 10;
198+
t = Math.floor(t / 10);
199+
}
200+
return x !== y;
201+
};
202+
return Array.from({ length: n }, (_, i) => i + 1).filter(check).length;
203+
}
204+
```
205+
183206
<!-- tabs:end -->
184207

185208
<!-- solution:end -->
@@ -204,18 +227,17 @@ $$
204227

205228
基本步骤如下:
206229

207-
1. 将数字 $n$ 转为 int 数组 $a,ドル其中 $a[1]$ 为最低位,而 $a[len]$ 为最高位;
208-
1. 根据题目信息,设计函数 $dfs(),ドル对于本题,我们定义 $dfs(pos, ok, limit),ドル答案为 $dfs(len, 0, true)$。
230+
我们将数字 $n$ 转为字符串 $s$。然后定义函数 $\textit{dfs}(i, \textit{ok}, \textit{limit}),ドル其中 $i$ 表示数字的位数,数字 $\textit{ok}$ 表示当前数字是否满足题目要求,布尔值 $\textit{limit}$ 表示可填的数字的限制。
209231

210-
其中:
232+
函数的执行逻辑如下:
211233

212-
- `pos` 表示数字的位数,从末位或者第一位开始,一般根据题目的数字构造性质来选择顺序。对于本题,我们选择从高位开始,因此,`pos` 的初始值为 `len`;
213-
- `ok` 表示当前数字是否满足题目要求(对于本题,如果数字出现 $[2, 5, 6, 9]$ 则满足)
214-
- `limit` 表示可填的数字的限制,如果无限制,那么可以选择 $[0,1,..9],ドル否则,只能选择 $[0,..a[pos]]$。如果 `limit``true` 且已经取到了能取到的最大值,那么下一个 `limit` 同样为 `true`;如果 `limit``true` 但是还没有取到最大值,或者 `limit``false`,那么下一个 `limit``false`
234+
如果 $i$ 大于等于字符串 $s$ 的长度,返回 $\textit{ok}$;
215235

216-
关于函数的实现细节,可以参考下面的代码。
236+
否则,我们获取当前位的数字 $up,ドル如果 $\textit{limit}$ 为 $\textit{true},ドル则 $up$ 为当前位的数字,否则 $up$ 为 9ドル$;
217237

218-
时间复杂度 $O(\log n)$。
238+
接下来,我们遍历 $[0,..up],ドル如果 $j$ 是有效数字 $[0, 1, 8],ドル则递归调用 $\textit{dfs}(i + 1, \textit{ok}, \textit{limit} \land j = \textit{up})$;如果 $j$ 是有效数字 $[2, 5, 6, 9],ドル则递归调用 $\textit{dfs}(i + 1, 1, \textit{limit} \land j = \textit{up})$;将所有递归调用的结果累加并返回。
239+
240+
时间复杂度 $O(\log n \times D),ドル空间复杂度 $O(\log n)$。其中 $D = 10$。
219241

220242
相似题目:
221243

@@ -234,65 +256,53 @@ $$
234256
class Solution:
235257
def rotatedDigits(self, n: int) -> int:
236258
@cache
237-
def dfs(pos, ok, limit):
238-
if pos <=0:
259+
def dfs(i: int, ok: int, limit: bool) -> int:
260+
if i >=len(s):
239261
return ok
240-
up = a[pos] if limit else 9
262+
up = int(s[i]) if limit else 9
241263
ans = 0
242-
for i in range(up + 1):
243-
if i in (0, 1, 8):
244-
ans += dfs(pos - 1, ok, limit and i == up)
245-
if i in (2, 5, 6, 9):
246-
ans += dfs(pos - 1, 1, limit and i == up)
264+
for j in range(up + 1):
265+
if j in (0, 1, 8):
266+
ans += dfs(i + 1, ok, limit and j == up)
267+
elif j in (2, 5, 6, 9):
268+
ans += dfs(i + 1, 1, limit and j == up)
247269
return ans
248270

249-
a = [0] * 6
250-
l = 1
251-
while n:
252-
a[l] = n % 10
253-
n //= 10
254-
l += 1
255-
return dfs(l, 0, True)
271+
s = str(n)
272+
return dfs(0, 0, True)
256273
```
257274

258275
#### Java
259276

260277
```java
261278
class Solution {
262-
private int[] a =newint[6];
263-
private int[][] dp =newint[6][2];
279+
private char[] s;
280+
private Integer[][] f;
264281

265282
public int rotatedDigits(int n) {
266-
int len = 0;
267-
for (var e : dp) {
268-
Arrays.fill(e, -1);
269-
}
270-
while (n > 0) {
271-
a[++len] = n % 10;
272-
n /= 10;
273-
}
274-
return dfs(len, 0, true);
283+
s = String.valueOf(n).toCharArray();
284+
f = new Integer[s.length][2];
285+
return dfs(0, 0, true);
275286
}
276287

277-
private int dfs(int pos, int ok, boolean limit) {
278-
if (pos <=0) {
288+
private int dfs(int i, int ok, boolean limit) {
289+
if (i >= s.length) {
279290
return ok;
280291
}
281-
if (!limit && dp[pos][ok] != -1) {
282-
return dp[pos][ok];
292+
if (!limit && f[i][ok] != null) {
293+
return f[i][ok];
283294
}
284-
int up = limit ? a[pos] : 9;
295+
int up = limit ? s[i] -'0' : 9;
285296
int ans = 0;
286-
for (int i = 0; i <= up; ++i) {
287-
if (i == 0 || i == 1 || i == 8) {
288-
ans += dfs(pos - 1, ok, limit && i == up);
289-
}
290-
if (i == 2 || i == 5 || i == 6 || i == 9) {
291-
ans += dfs(pos - 1, 1, limit && i == up);
297+
for (int j = 0; j <= up; ++j) {
298+
if (j == 0 || j == 1 || j == 8) {
299+
ans += dfs(i + 1, ok, limit && j == up);
300+
} else if (j == 2 || j == 5 || j == 6 || j == 9) {
301+
ans += dfs(i + 1, 1, limit && j == up);
292302
}
293303
}
294304
if (!limit) {
295-
dp[pos][ok] = ans;
305+
f[i][ok] = ans;
296306
}
297307
return ans;
298308
}
@@ -304,40 +314,33 @@ class Solution {
304314
```cpp
305315
class Solution {
306316
public:
307-
int a[6];
308-
int dp[6][2];
309-
310317
int rotatedDigits(int n) {
311-
memset(dp, -1, sizeof dp);
312-
int len = 0;
313-
while (n) {
314-
a[++len] = n % 10;
315-
n /= 10;
316-
}
317-
return dfs(len, 0, true);
318-
}
319-
320-
int dfs(int pos, int ok, bool limit) {
321-
if (pos <= 0) {
322-
return ok;
323-
}
324-
if (!limit && dp[pos][ok] != -1) {
325-
return dp[pos][ok];
326-
}
327-
int up = limit ? a[pos] : 9;
328-
int ans = 0;
329-
for (int i = 0; i <= up; ++i) {
330-
if (i == 0 || i == 1 || i == 8) {
331-
ans += dfs(pos - 1, ok, limit && i == up);
318+
string s = to_string(n);
319+
int m = s.size();
320+
int f[m][2];
321+
memset(f, -1, sizeof(f));
322+
auto dfs = [&](auto&& dfs, int i, int ok, bool limit) -> int {
323+
if (i >= m) {
324+
return ok;
332325
}
333-
if (i == 2 || i == 5 || i == 6 || i == 9) {
334-
ans += dfs(pos - 1, 1, limit && i == up);
326+
if (!limit && f[i][ok] != -1) {
327+
return f[i][ok];
335328
}
336-
}
337-
if (!limit) {
338-
dp[pos][ok] = ans;
339-
}
340-
return ans;
329+
int up = limit ? s[i] - '0' : 9;
330+
int ans = 0;
331+
for (int j = 0; j <= up; ++j) {
332+
if (j == 0 || j == 1 || j == 8) {
333+
ans += dfs(dfs, i + 1, ok, limit && j == up);
334+
} else if (j == 2 || j == 5 || j == 6 || j == 9) {
335+
ans += dfs(dfs, i + 1, 1, limit && j == up);
336+
}
337+
}
338+
if (!limit) {
339+
f[i][ok] = ans;
340+
}
341+
return ans;
342+
};
343+
return dfs(dfs, 0, 0, true);
341344
}
342345
};
343346
```
@@ -346,46 +349,70 @@ public:
346349
347350
```go
348351
func rotatedDigits(n int) int {
349-
a := make([]int, 6)
350-
dp := make([][2]int, 6)
351-
for i := range a {
352-
dp[i] = [2]int{-1, -1}
352+
s := strconv.Itoa(n)
353+
m := len(s)
354+
f := make([][2]int, m)
355+
for i := range f {
356+
f[i] = [2]int{-1, -1}
353357
}
354-
l := 0
355-
for n > 0 {
356-
l++
357-
a[l] = n % 10
358-
n /= 10
359-
}
360-
361-
var dfs func(int, int, bool) int
362-
dfs = func(pos, ok int, limit bool) int {
363-
if pos <= 0 {
358+
var dfs func(i, ok int, limit bool) int
359+
dfs = func(i, ok int, limit bool) int {
360+
if i >= m {
364361
return ok
365362
}
366-
if !limit && dp[pos][ok] != -1 {
367-
return dp[pos][ok]
363+
if !limit && f[i][ok] != -1 {
364+
return f[i][ok]
368365
}
369366
up := 9
370367
if limit {
371-
up = a[pos]
368+
up = int(s[i] - '0')
372369
}
373370
ans := 0
374-
for i := 0; i <= up; i++ {
375-
if i == 0 || i == 1 || i == 8 {
376-
ans += dfs(pos-1, ok, limit && i == up)
377-
}
378-
if i == 2 || i == 5 || i == 6 || i == 9 {
379-
ans += dfs(pos-1, 1, limit && i == up)
371+
for j := 0; j <= up; j++ {
372+
if j == 0 || j == 1 || j == 8 {
373+
ans += dfs(i+1, ok, limit && j == up)
374+
} else if j == 2 || j == 5 || j == 6 || j == 9 {
375+
ans += dfs(i+1, 1, limit && j == up)
380376
}
381377
}
382378
if !limit {
383-
dp[pos][ok] = ans
379+
f[i][ok] = ans
384380
}
385381
return ans
386382
}
383+
return dfs(0, 0, true)
384+
}
385+
```
386+
387+
#### TypeScript
387388

388-
return dfs(l, 0, true)
389+
```ts
390+
function rotatedDigits(n: number): number {
391+
const s = n.toString();
392+
const m = s.length;
393+
const f: number[][] = Array.from({ length: m }, () => Array(2).fill(-1));
394+
const dfs = (i: number, ok: number, limit: boolean): number => {
395+
if (i >= m) {
396+
return ok;
397+
}
398+
if (!limit && f[i][ok] !== -1) {
399+
return f[i][ok];
400+
}
401+
const up = limit ? +s[i] : 9;
402+
let ans = 0;
403+
for (let j = 0; j <= up; ++j) {
404+
if ([0, 1, 8].includes(j)) {
405+
ans += dfs(i + 1, ok, limit && j === up);
406+
} else if ([2, 5, 6, 9].includes(j)) {
407+
ans += dfs(i + 1, 1, limit && j === up);
408+
}
409+
}
410+
if (!limit) {
411+
f[i][ok] = ans;
412+
}
413+
return ans;
414+
};
415+
return dfs(0, 0, true);
389416
}
390417
```
391418

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /