1.问题
一个坐标可以从 -infinity
延伸到 +infinity
的 无限大的 棋盘上,你的 骑士 驻扎在坐标为 [0, 0]
的方格里。
骑士的走法和中国象棋中的马相似,走 “日” 字:即先向左(或右)走 1 格,再向上(或下)走 2 格;或先向左(或右)走 2 格,再向上(或下)走 1 格。
每次移动,他都可以按图示八个方向之一前进。
现在,骑士需要前去征服坐标为 [x, y]
的部落,请你为他规划路线。
最后返回所需的最小移动次数即可。本题确保答案是一定存在的。
示例 1:
输入:x = 2, y = 1
输出:1
解释:[0, 0] → [2, 1]
提示:
|x| + |y| <= 300
原题链接;
2.解答
宽度优先搜索,并且把visited
的点保存下来。
class Solution {
public int minKnightMoves(int x, int y) {
int[] dx = {-1, -1, 1, 1, -2, -2, 2, 2};
int[] dy = {2, -2, 2, -2, 1, -1, 1, -1};
Set<Integer> visited = new HashSet<>();
int M = 10000;
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[] {0, 0});
visited.add(0 * M + 0);
int res = 0;
if (x == 0 && y == 0) return 0;
while (!queue.isEmpty()) {
int sz = queue.size();
res++;
for (int i = 0; i < sz; i++) {
int[] cur = queue.poll();
for (int k = 0; k < dx.length; k++) {
int nx = cur[0] + dx[k];
int ny = cur[1] + dy[k];
if (nx == x && ny == y) return res;
if (visited.contains(nx * M + ny)) continue;
queue.add(new int[] {nx, ny});
visited.add(nx * M + ny);
}
}
}
return -1;
}
}