我们都知道安卓有个手势解锁的界面,是一个 3 x 3 的点所绘制出来的网格。用户可以设置一个 “解锁模式” ,通过连接特定序列中的点,形成一系列彼此连接的线段,每个线段的端点都是序列中两个连续的点。如果满足以下两个条件,则 k 点序列是有效的解锁模式:
解锁模式中的所有点 互不相同 。
假如模式中两个连续点的线段需要经过其他点,那么要经过的点必须事先出现在序列中(已经经过),不能跨过任何还未被经过的点。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/android-unlock-patterns
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
import java.util.Arrays;
public class Solution {
private boolean used[] = new boolean[9];
public int numberOfPatterns(int n, int m) {
int res = 0;
for (int len = n; len <= m; len++) {
res += calcPatterns(-1, len);
Arrays.fill(used, false);
}
return res;
}
private boolean isValid(int index, int last) {
if (used[index])
return false;
// first digit of the pattern
if (last == -1)
return true;
// knight moves or adjacent cells (in a row or in a column)
if ((index + last) % 2 == 1)
return true;
// indexes are at both end of the diagonals for example 0,0, and 8,8
int mid = (index + last) / 2;
if (mid == 4)
return used[mid];
// adjacent cells on diagonal - for example 0,0 and 1,0 or 2,0 and //1,1
if ((index % 3 != last % 3) && (index / 3 != last / 3)) {
return true;
}
// all other cells which are not adjacent
return used[mid];
}
// 0 1 2
// 3 4 5
// 6 7 8
private int calcPatterns(int last, int len) {
if (len == 0)
return 1;
int sum = 0;
for (int i = 0; i < 9; i++) {
if (isValid(i, last)) {
used[i] = true;
sum += calcPatterns(i, len - 1);
used[i] = false;
}
}
return sum;
}
}