Approach 1: BFS
BFS 模版
class Solution {
private final int[][] DIRECTIONS = new int[][] {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}};
public int BFS(int x, int y) {
x = Math.abs(x);
y = Math.abs(y);
Queue<int[]> queue = new LinkedList<>(); // 记录每一层的节点
queue.add(new int[] {0, 0});
Set<String> visited = new HashSet<>();//记录是否访问过,也可以用二维boolean数组
visited.add("0,0");
int result = 0;
while (!queue.isEmpty()) {
int size = queue.size(); //得到每一层的节点数
for (int i = 0; i < size; i++) {
int[] cur = queue.remove();
int curX = cur[0];
int curY = cur[1];
if (curX == x && curY == y) {
return result;
}
for (int[] d : DIRECTIONS) {// bfs遍历一个节点的下一层
int newX = curX + d[0];
int newY = curY + d[1];
if (!visited.contains(newX + "," + newY) && newX >= -1 && newY >= -1) {// 先判断是否访问过, 再确定边界条件
queue.add(new int[] {newX, newY});
visited.add(newX + "," + newY);
}
}
}
result++;
}
return -1;
}
}
simple BFA
why newX >= -1 && newY >= -1) instead of newX >= 0 && newY >= 0)?
The co-or in general to compute the knight moves are: (x-2, y-1) (x-2, y+1), (x-1, y-2) … where for all x,y>=2 the next “move” will always be >=0 (ie in the first quadrant). Only for x=1/y=1, the next move may fall in the negative quad example (x-2,y-1) or (x-1, y-2), and hence x=-1 y=-1 boundary is considered.
int[][] dirs = new int[][] {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}};
(0,0) ->(2,1)
(0,0) ->(1,2)
(0,0) ->(-1,2)
(0,0) ->(-2,1) , not ok
(0,0) ->(-2,-1), not ok
(0,0) ->(-1,-2), not ok
(0,0) ->(1, -2), not ok
(0,0) ->(2,-1)
Approach 2: The Formula
Since it is symmetric vertically, horizontally and diagonally, we can format x and y in the following way, so that every target node falls into the region enclosesd by the black lines
The formula
Math