骑士巡视问题
题目描述
给定一个 n x n 的整数矩阵 grid
,其中 grid[row][col]
表示单元格 (row, col)
是骑士访问的第 grid[row][col]
个单元格。骑士的行动是从下标 0 开始的。骑士可以进行以下两种移动:
- 垂直移动两个格子且水平移动一个格子。
- 水平移动两个格子且垂直移动一个格子。
如果 grid
表示了骑士的有效巡视方案,返回 true
;否则返回 false
。
解决方案
我们可以使用深度优先搜索(DFS)来验证是否存在有效的巡视方案。从左上角出发,我们尝试所有可能的移动方向,并检查是否可以完成所有步数。以下是解决方案的代码:
class Solution {
public:
bool checkValidGrid(vector<vector<int>>& grid) {
int n = grid.size();
int totalSteps = n * n;
vector<vector<bool>> visited(n, vector<bool>(n, false));
// 从左上角出发,初始步数为0
return dfs(grid, visited, 0, 0, 0, totalSteps);
}
bool dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y, int step, int totalSteps) {
if (step == totalSteps - 1) {
// 已经完成所有步数
return true;
}
visited[x][y] = true;
// 8种可能的移动方向
int dx[] = {-1, -1, 1, 1, -2, -2, 2, 2};
int dy[] = {-2, 2, -2, 2, -1, 1, -1, 1};
for (int i = 0; i < 8; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && nx < grid.size() && ny >= 0 && ny < grid[0].size() && !visited[nx][ny]) {
int nextStep = step + 1;
int cellValue = grid[nx][ny];
if (cellValue == nextStep && dfs(grid, visited, nx, ny, nextStep, totalSteps)) {
return true;
}
}
}
visited[x][y] = false; // 回溯
return false;
}
};