Skip to content

Commit d11fa4c

Browse files
authored
feat: add solutions to lc problem: No.0351 (#1310)
No.0351.Android Unlock Patterns
1 parent b8d7b5c commit d11fa4c

File tree

7 files changed

+562
-1
lines changed

7 files changed

+562
-1
lines changed

solution/0300-0399/0351.Android Unlock Patterns/README.md

+211-1
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,232 @@
6161

6262
<!-- 这里可写通用的实现逻辑 -->
6363

64+
**方法一:DFS**
65+
66+
我们定义一个二维数组 $cross$,其中 $cross[i][j]$ 表示数字 $i$ 和数字 $j$ 之间是否有中间数字,如果有则 $cross[i][j]$ 的值为中间数字,否则为 $0$。
67+
68+
我们还需要一个一维数组 $vis$,用来记录数字是否被使用过。
69+
70+
由于数字 $1$, $3$, $7$, $9$ 是对称的,因此我们只需要计算数字 $1$ 的情况,然后乘以 $4$ 即可。
71+
72+
由于数字 $2$, $4$, $6$, $8$ 也是对称的,因此我们只需要计算数字 $2$ 的情况,然后乘以 $4$ 即可。
73+
74+
最后我们再计算数字 $5$ 的情况。
75+
76+
我们设计一个函数 $dfs(i, cnt)$,表示当前位于数字 $i$,且已经选了 $cnt$ 个数字的情况下,有多少种解锁模式。
77+
78+
函数 $dfs(i, cnt)$ 的执行过程如下:
79+
80+
如果 $cnt \gt n$,说明当前选中的数字个数超过了 $n$,直接返回 $0$。
81+
82+
否则,我们将数字 $i$ 标记为已使用,然后初始化答案 $ans$ 为 $0$。如果 $cnt \ge m$,说明当前选中的数字个数不少于 $m$,那么答案 $ans$ 就需要加 $1$。
83+
84+
接下来,我们枚举下一个数字 $j$,如果数字 $j$ 没有被使用过,且数字 $i$ 和数字 $j$ 之间没有中间数字,或者数字 $i$ 和数字 $j$ 之间的中间数字已经被使用过,那么我们就可以从数字 $j$ 出发,继续搜索,此时答案 $ans$ 需要加上 $dfs(j, cnt + 1)$ 的返回值。
85+
86+
最后,我们将数字 $i$ 标记为未使用,然后返回答案 $ans$。
87+
88+
最终的答案即为 $dfs(1, 1) \times 4 + dfs(2, 1) \times 4 + dfs(5, 1)$。
89+
90+
时间复杂度 $O(n!)$,空间复杂度 $O(n)$。其中 $n$ 是手势的最大长度。
91+
6492
<!-- tabs:start -->
6593

6694
### **Python3**
6795

6896
<!-- 这里可写当前语言的特殊实现逻辑 -->
6997

7098
```python
71-
99+
class Solution:
100+
def numberOfPatterns(self, m: int, n: int) -> int:
101+
def dfs(i: int, cnt: int = 1) -> int:
102+
if cnt > n:
103+
return 0
104+
vis[i] = True
105+
ans = int(cnt >= m)
106+
for j in range(1, 10):
107+
x = cross[i][j]
108+
if not vis[j] and (x == 0 or vis[x]):
109+
ans += dfs(j, cnt + 1)
110+
vis[i] = False
111+
return ans
112+
113+
cross = [[0] * 10 for _ in range(10)]
114+
cross[1][3] = cross[3][1] = 2
115+
cross[1][7] = cross[7][1] = 4
116+
cross[1][9] = cross[9][1] = 5
117+
cross[2][8] = cross[8][2] = 5
118+
cross[3][7] = cross[7][3] = 5
119+
cross[3][9] = cross[9][3] = 6
120+
cross[4][6] = cross[6][4] = 5
121+
cross[7][9] = cross[9][7] = 8
122+
vis = [False] * 10
123+
return dfs(1) * 4 + dfs(2) * 4 + dfs(5)
72124
```
73125

74126
### **Java**
75127

76128
<!-- 这里可写当前语言的特殊实现逻辑 -->
77129

78130
```java
131+
class Solution {
132+
private int m;
133+
private int n;
134+
private int[][] cross = new int[10][10];
135+
private boolean[] vis = new boolean[10];
136+
137+
public int numberOfPatterns(int m, int n) {
138+
this.m = m;
139+
this.n = n;
140+
cross[1][3] = cross[3][1] = 2;
141+
cross[1][7] = cross[7][1] = 4;
142+
cross[1][9] = cross[9][1] = 5;
143+
cross[2][8] = cross[8][2] = 5;
144+
cross[3][7] = cross[7][3] = 5;
145+
cross[3][9] = cross[9][3] = 6;
146+
cross[4][6] = cross[6][4] = 5;
147+
cross[7][9] = cross[9][7] = 8;
148+
return dfs(1, 1) * 4 + dfs(2, 1) * 4 + dfs(5, 1);
149+
}
150+
151+
private int dfs(int i, int cnt) {
152+
if (cnt > n) {
153+
return 0;
154+
}
155+
vis[i] = true;
156+
int ans = cnt >= m ? 1 : 0;
157+
for (int j = 1; j < 10; ++j) {
158+
int x = cross[i][j];
159+
if (!vis[j] && (x == 0 || vis[x])) {
160+
ans += dfs(j, cnt + 1);
161+
}
162+
}
163+
vis[i] = false;
164+
return ans;
165+
}
166+
}
167+
```
168+
169+
### **C++**
170+
171+
```cpp
172+
class Solution {
173+
public:
174+
int numberOfPatterns(int m, int n) {
175+
int cross[10][10];
176+
memset(cross, 0, sizeof(cross));
177+
bool vis[10];
178+
memset(vis, false, sizeof(vis));
179+
cross[1][3] = cross[3][1] = 2;
180+
cross[1][7] = cross[7][1] = 4;
181+
cross[1][9] = cross[9][1] = 5;
182+
cross[2][8] = cross[8][2] = 5;
183+
cross[3][7] = cross[7][3] = 5;
184+
cross[3][9] = cross[9][3] = 6;
185+
cross[4][6] = cross[6][4] = 5;
186+
cross[7][9] = cross[9][7] = 8;
187+
188+
function<int(int, int)> dfs = [&](int i, int cnt) {
189+
if (cnt > n) {
190+
return 0;
191+
}
192+
vis[i] = true;
193+
int ans = cnt >= m ? 1 : 0;
194+
for (int j = 1; j < 10; ++j) {
195+
int x = cross[i][j];
196+
if (!vis[j] && (x == 0 || vis[x])) {
197+
ans += dfs(j, cnt + 1);
198+
}
199+
}
200+
vis[i] = false;
201+
return ans;
202+
};
203+
204+
return dfs(1, 1) * 4 + dfs(2, 1) * 4 + dfs(5, 1);
205+
}
206+
};
207+
```
208+
209+
### **Go**
210+
211+
```go
212+
func numberOfPatterns(m int, n int) int {
213+
cross := [10][10]int{}
214+
vis := [10]bool{}
215+
cross[1][3] = 2
216+
cross[1][7] = 4
217+
cross[1][9] = 5
218+
cross[2][8] = 5
219+
cross[3][7] = 5
220+
cross[3][9] = 6
221+
cross[4][6] = 5
222+
cross[7][9] = 8
223+
cross[3][1] = 2
224+
cross[7][1] = 4
225+
cross[9][1] = 5
226+
cross[8][2] = 5
227+
cross[7][3] = 5
228+
cross[9][3] = 6
229+
cross[6][4] = 5
230+
cross[9][7] = 8
231+
var dfs func(int, int) int
232+
dfs = func(i, cnt int) int {
233+
if cnt > n {
234+
return 0
235+
}
236+
vis[i] = true
237+
ans := 0
238+
if cnt >= m {
239+
ans++
240+
}
241+
for j := 1; j < 10; j++ {
242+
x := cross[i][j]
243+
if !vis[j] && (x == 0 || vis[x]) {
244+
ans += dfs(j, cnt+1)
245+
}
246+
}
247+
vis[i] = false
248+
return ans
249+
}
250+
return dfs(1, 1)*4 + dfs(2, 1)*4 + dfs(5, 1)
251+
}
252+
```
79253

254+
### **TypeScript**
255+
256+
```ts
257+
function numberOfPatterns(m: number, n: number): number {
258+
const cross: number[][] = Array(10)
259+
.fill(0)
260+
.map(() => Array(10).fill(0));
261+
const vis: boolean[] = Array(10).fill(false);
262+
cross[1][3] = cross[3][1] = 2;
263+
cross[1][7] = cross[7][1] = 4;
264+
cross[1][9] = cross[9][1] = 5;
265+
cross[2][8] = cross[8][2] = 5;
266+
cross[3][7] = cross[7][3] = 5;
267+
cross[3][9] = cross[9][3] = 6;
268+
cross[4][6] = cross[6][4] = 5;
269+
cross[7][9] = cross[9][7] = 8;
270+
const dfs = (i: number, cnt: number): number => {
271+
if (cnt > n) {
272+
return 0;
273+
}
274+
vis[i] = true;
275+
let ans = 0;
276+
if (cnt >= m) {
277+
++ans;
278+
}
279+
for (let j = 1; j < 10; ++j) {
280+
const x = cross[i][j];
281+
if (!vis[j] && (x === 0 || vis[x])) {
282+
ans += dfs(j, cnt + 1);
283+
}
284+
}
285+
vis[i] = false;
286+
return ans;
287+
};
288+
return dfs(1, 1) * 4 + dfs(2, 1) * 4 + dfs(5, 1);
289+
}
80290
```
81291

82292
### **...**

0 commit comments

Comments
 (0)