Given an Android 3x3 key lock screen and two integers m and n, where 1 ≤ m ≤ n ≤ 9, count the total number of unlock patterns of the Android lock screen, which consist of minimum of m keys and maximum n keys.
Rules for a valid pattern:
Each pattern must connect at least m keys and at most n keys.
All the keys must be distinct.
If the line connecting two consecutive keys in the pattern passes through any other keys, the other keys must have previously selected in the pattern. No jumps through non selected key is allowed.
The order of keys used matters.
Explanation:
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
Invalid move: 4 - 1 - 3 - 6
Line 1 - 3 passes through key 2 which had not been selected in the pattern.
Invalid move: 4 - 1 - 9 - 2
Line 1 - 9 passes through key 5 which had not been selected in the pattern.
Valid move: 2 - 4 - 1 - 3 - 6
Line 1 - 3 is valid because it passes through key 2, which had been selected in the pattern
Valid move: 6 - 5 - 4 - 1 - 9 - 2
Line 1 - 9 is valid because it passes through key 5, which had been selected in the pattern.
Example:
Given m = 1, n = 1, return 9.
解法1:
这题一拿到感觉是dp或者是dfs的题目。用dp想不出状态方程看来只能用dfs试一下。
dfs的话最核心的思想就是每次往目标前进一步,如果成功则再继续探寻。
这个问题的一部是要看上一步和当前一步是否构成一个合适的movement.
一定是:
1. 相邻的
2. 对线的
3. 不相邻但是当中的数字已经被访问过了
那么用一个数组维护访问过的数字,同时维护一个上次访问的数字和当前的数字,以便判断一个move是否合适。
对于每一个数字进行dfs遍历,每前进一步就把所剩的步数-1.
C++
Java
解法2:
由于可能的跳跃是有限的,可以用一个table来存储合法的跳跃path。这样可以简化很多检查一个move是否合法的code。
每次DFS的时候从一个点开始,找出可能的path。同时利用对称性,1,3,7,9是一样的;2,4,6,8是一样的。5单独一个。
|
|