骑士在一张 n x n 的棋盘上巡视。在有效的巡视方案中,骑士会从棋盘的 左上角 出发,并且访问棋盘上的每个格子 恰好一次 。
给你一个 n x n 的整数矩阵 grid ,由范围 [0, n * n - 1] 内的不同整数组成,其中 grid[row][col] 表示单元格 (row, col) 是骑士访问的第 grid[row][col] 个单元格。骑士的行动是从下标 0 开始的。
如果 grid 表示了骑士的有效巡视方案,返回 true;否则返回 false。
注意,骑士行动时可以垂直移动两个格子且水平移动一个格子,或水平移动两个格子且垂直移动一个格子。下图展示了骑士从某个格子出发可能的八种行动路线。
示例 1:
输入: grid = [[0,11,16,5,20],[17,4,19,10,15],[12,1,8,21,6],[3,18,23,14,9],[24,13,2,7,22]]
输出: true
解释: grid 如上图所示,可以证明这是一个有效的巡视方案。
示例 2:
输入: grid = [[0,3,6],[5,8,1],[2,7,4]]
输出: false
解释: grid 如上图所示,考虑到骑士第 7 次行动后的位置,第 8 次行动是无效的。
提示:
n == grid.length == grid[i].length3 <= n <= 70 <= grid[row][col] < n * ngrid中的所有整数 互不相同
思路
由题目知,如果方案可行,需满足两个条件:
- 骑士需从左上角开始,即
grid[0][0] = 0 - 按照骑士需访问棋盘上每个格子恰好一次。
骑士的走法根中国象棋中的马一样,只能走日,设当前骑士的位置为[x, y]下一步的位置需满足[xi, yi]需满足: |xi - x| = 2 && |yi - y| = 1 或者 |xi - x| = 1 && |yi - y| = 2 ,即|xi - x| * |yi - y| = 2
我们先遍历棋盘,记录下每一步的位置,然后判断相邻的两步是否满足上述条件即可。
解题
/**
* @param {number[][]} grid
* @return {boolean}
*/
var checkValidGrid = function (grid) {
if (grid[0][0] != 0) {
return false;
}
const n = grid.length;
const arr = Array(n * n).fill(0);
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
arr[grid[i][j]] = [i, j];
}
}
for (let i = 1; i < arr.length; i++) {
let x = arr[i][0] - arr[i - 1][0];
let y = arr[i][1] - arr[i - 1][1];
if (Math.abs(x * y) !== 2) {
return false;
}
}
return true;
};