comments | difficulty | edit_url | tags | ||||
---|---|---|---|---|---|---|---|
true |
中等 |
|
我们都知道安卓有个手势解锁的界面,是一个 3 x 3
的点所绘制出来的网格。用户可以设置一个 “解锁模式” ,通过连接特定序列中的点,形成一系列彼此连接的线段,每个线段的端点都是序列中两个连续的点。如果满足以下两个条件,则 k
点序列是有效的解锁模式:
- 解锁模式中的所有点 互不相同 。
- 假如模式中两个连续点的线段需要经过其他点的 中心 ,那么要经过的点 必须提前出现 在序列中(已经经过),不能跨过任何还未被经过的点。
- 例如,点
5
或6
没有提前出现的情况下连接点2
和9
是有效的,因为从点2
到点9
的线没有穿过点5
或6
的中心。 - 然而,点
2
没有提前出现的情况下连接点1
和3
是无效的,因为从圆点1
到圆点3
的直线穿过圆点2
的中心。
- 例如,点
以下是一些有效和无效解锁模式的示例:
- 无效手势:
[4,1,3,6]
,连接点 1 和点 3 时经过了未被连接过的 2 号点。 - 无效手势:
[4,1,9,2]
,连接点 1 和点 9 时经过了未被连接过的 5 号点。 - 有效手势:
[2,4,1,3,6]
,连接点 1 和点 3 是有效的,因为虽然它经过了点 2 ,但是点 2 在该手势中之前已经被连过了。 - 有效手势:
[6,5,4,1,9,2]
,连接点 1 和点 9 是有效的,因为虽然它经过了按键 5 ,但是点 5 在该手势中之前已经被连过了。
给你两个整数,分别为 m
和 n
,那么请返回有多少种 不同且有效的解锁模式 ,是 至少 需要经过 m
个点,但是 不超过 n
个点的。
两个解锁模式 不同 需满足:经过的点不同或者经过点的顺序不同。
示例 1:
输入:m = 1, n = 1 输出:9
示例 2:
输入:m = 1, n = 2 输出:65
提示:
1 <= m, n <= 9
我们定义一个二维数组
我们还需要一个一维数组
由于数字
由于数字
最后我们再计算数字
我们设计一个函数
函数
如果
否则,我们将数字
接下来,我们枚举下一个数字
最后,我们将数字
最终的答案即为
时间复杂度
class Solution:
def numberOfPatterns(self, m: int, n: int) -> int:
def dfs(i: int, cnt: int = 1) -> int:
if cnt > n:
return 0
vis[i] = True
ans = int(cnt >= m)
for j in range(1, 10):
x = cross[i][j]
if not vis[j] and (x == 0 or vis[x]):
ans += dfs(j, cnt + 1)
vis[i] = False
return ans
cross = [[0] * 10 for _ in range(10)]
cross[1][3] = cross[3][1] = 2
cross[1][7] = cross[7][1] = 4
cross[1][9] = cross[9][1] = 5
cross[2][8] = cross[8][2] = 5
cross[3][7] = cross[7][3] = 5
cross[3][9] = cross[9][3] = 6
cross[4][6] = cross[6][4] = 5
cross[7][9] = cross[9][7] = 8
vis = [False] * 10
return dfs(1) * 4 + dfs(2) * 4 + dfs(5)
class Solution {
private int m;
private int n;
private int[][] cross = new int[10][10];
private boolean[] vis = new boolean[10];
public int numberOfPatterns(int m, int n) {
this.m = m;
this.n = n;
cross[1][3] = cross[3][1] = 2;
cross[1][7] = cross[7][1] = 4;
cross[1][9] = cross[9][1] = 5;
cross[2][8] = cross[8][2] = 5;
cross[3][7] = cross[7][3] = 5;
cross[3][9] = cross[9][3] = 6;
cross[4][6] = cross[6][4] = 5;
cross[7][9] = cross[9][7] = 8;
return dfs(1, 1) * 4 + dfs(2, 1) * 4 + dfs(5, 1);
}
private int dfs(int i, int cnt) {
if (cnt > n) {
return 0;
}
vis[i] = true;
int ans = cnt >= m ? 1 : 0;
for (int j = 1; j < 10; ++j) {
int x = cross[i][j];
if (!vis[j] && (x == 0 || vis[x])) {
ans += dfs(j, cnt + 1);
}
}
vis[i] = false;
return ans;
}
}
class Solution {
public:
int numberOfPatterns(int m, int n) {
int cross[10][10];
memset(cross, 0, sizeof(cross));
bool vis[10];
memset(vis, false, sizeof(vis));
cross[1][3] = cross[3][1] = 2;
cross[1][7] = cross[7][1] = 4;
cross[1][9] = cross[9][1] = 5;
cross[2][8] = cross[8][2] = 5;
cross[3][7] = cross[7][3] = 5;
cross[3][9] = cross[9][3] = 6;
cross[4][6] = cross[6][4] = 5;
cross[7][9] = cross[9][7] = 8;
function<int(int, int)> dfs = [&](int i, int cnt) {
if (cnt > n) {
return 0;
}
vis[i] = true;
int ans = cnt >= m ? 1 : 0;
for (int j = 1; j < 10; ++j) {
int x = cross[i][j];
if (!vis[j] && (x == 0 || vis[x])) {
ans += dfs(j, cnt + 1);
}
}
vis[i] = false;
return ans;
};
return dfs(1, 1) * 4 + dfs(2, 1) * 4 + dfs(5, 1);
}
};
func numberOfPatterns(m int, n int) int {
cross := [10][10]int{}
vis := [10]bool{}
cross[1][3] = 2
cross[1][7] = 4
cross[1][9] = 5
cross[2][8] = 5
cross[3][7] = 5
cross[3][9] = 6
cross[4][6] = 5
cross[7][9] = 8
cross[3][1] = 2
cross[7][1] = 4
cross[9][1] = 5
cross[8][2] = 5
cross[7][3] = 5
cross[9][3] = 6
cross[6][4] = 5
cross[9][7] = 8
var dfs func(int, int) int
dfs = func(i, cnt int) int {
if cnt > n {
return 0
}
vis[i] = true
ans := 0
if cnt >= m {
ans++
}
for j := 1; j < 10; j++ {
x := cross[i][j]
if !vis[j] && (x == 0 || vis[x]) {
ans += dfs(j, cnt+1)
}
}
vis[i] = false
return ans
}
return dfs(1, 1)*4 + dfs(2, 1)*4 + dfs(5, 1)
}
function numberOfPatterns(m: number, n: number): number {
const cross: number[][] = Array(10)
.fill(0)
.map(() => Array(10).fill(0));
const vis: boolean[] = Array(10).fill(false);
cross[1][3] = cross[3][1] = 2;
cross[1][7] = cross[7][1] = 4;
cross[1][9] = cross[9][1] = 5;
cross[2][8] = cross[8][2] = 5;
cross[3][7] = cross[7][3] = 5;
cross[3][9] = cross[9][3] = 6;
cross[4][6] = cross[6][4] = 5;
cross[7][9] = cross[9][7] = 8;
const dfs = (i: number, cnt: number): number => {
if (cnt > n) {
return 0;
}
vis[i] = true;
let ans = 0;
if (cnt >= m) {
++ans;
}
for (let j = 1; j < 10; ++j) {
const x = cross[i][j];
if (!vis[j] && (x === 0 || vis[x])) {
ans += dfs(j, cnt + 1);
}
}
vis[i] = false;
return ans;
};
return dfs(1, 1) * 4 + dfs(2, 1) * 4 + dfs(5, 1);
}