This problem asks to find the number of valid unlock patterns of length at least m
and at most n
on a 3x3 grid. A pattern is valid if:
The solution uses Depth-First Search (DFS) with backtracking and a clever optimization to avoid redundant computations.
1. cross
array: This 10x10 array stores the "jump-over" information. cross[i][j]
represents the dot that lies between dot i
and dot j
if such a dot exists. If no dot lies between i
and j
, the value is 0.
2. dfs(i, cnt)
function: This is the recursive DFS function.
i
: The index of the current dot being considered (1-9).cnt
: The length of the current pattern.i
as visited (vis[i] = true
).cnt
) is within the allowed range (m
to n
), it adds 1 to the count of valid patterns.j
is not visited and the condition for passing through the center is met (cross[i][j] == 0
or vis[cross[i][j]]
), it recursively calls dfs(j, cnt + 1)
.vis[i] = false
) to backtrack.3. Symmetry Optimization: The solution leverages symmetry to reduce computations. Instead of exploring all possible starting points (1-9), it only explores three: 1, 2, and 5.
The total number of unique patterns is calculated as dfs(1, 1) * 4 + dfs(2, 1) * 4 + dfs(5, 1)
.
Time Complexity: O(N), where N is the number of possible valid patterns. Although it appears exponential at first glance due to the recursion, the pruning from the cross
array and symmetry dramatically reduces the number of explored paths. The number of possible patterns is far less than the theoretical maximum (9!).
Space Complexity: O(1). The cross
array and vis
array are of constant size. The recursive call stack's depth is at most 9 (maximum pattern length).
The code implementations in Python, Java, C++, Go, and TypeScript are provided in the problem description. They all follow the same algorithm described above. The differences are mostly syntactical.