# 351 安卓系统手势解锁
# 题目链接
# 难度:中等
# 思路分析:
针对一些链接点,需要先链接其他点。
# 想
# 一
# 想
# 再
# 看
# 答
# 案
# 想
# 一
# 想
# 再
# 看
# 答
# 案
# 代码:
/**
* @param {number} m
* @param {number} n
* @return {number}
*/
// 回溯
var numberOfPatterns = function(m, n) {
let result = 0
// 两个点之间必须要经过的点
let S = {
'1 3': 2,
'4 6': 5,
'7 9': 8,
'1 7': 4,
'2 8': 5,
'3 9': 6,
'1 9': 5,
'3 7': 5,
'3 1': 2,
'6 4': 5,
'9 7': 8,
'7 1': 4,
'8 2': 5,
'9 3': 6,
'9 1': 5,
'7 3': 5
}
// 最小连接数量和最大连接数量
for (let i = m; i <= n; i++) helper(i)
return result
/**
* @param {number} n 已连接多少点
* @param {number} l 当前出发点
* @param {number} s 之前连接点的字符
*/
function helper(n, l = undefined, s = '') {
if (n === 0) return (result += 1) // 连接的点够了 增加一种方案
// 从1开始 每个点都作为起始点
for (let i = 1; i <= 9; i++) {
if (l) {
let k = l + ' ' + i
// 当前点是否连接过 连接过不操作
if (s.indexOf(i) === -1) {
// 是否需要经过中间的点
if (S[k] !== undefined) {
// 在s中找到中间点 继续从i连接的点出发
if (s.indexOf(S[k]) > -1) helper(n - 1, i, s + i)
// 没找到中间点不操作 回溯 说明不能连接这两个点
} else {
// 不经过 回溯 从连接的点再出发
helper(n - 1, i, s + i)
}
}
} else {
// 连接上初始点
helper(n - 1, i, s + i)
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# 鼓励我一下:
觉得还不错的话,给我的项目点个star吧