一刷
Version #1 BFS
TLE if we use HashMap to implement the visited grids
We should use a boolean array instead
Given the coordinate of the target as , the number of cells covered by the circle that is centered at point and reaches the target point is roughly
Time O(max(|x|, |y|)^2)
Space O(max(|x|, |y|)^2)
class Solution {
private int[] dx = new int[]{2, 1, -1, -2, -2, -1, 1, 2};
private int[] dy = new int[]{1, 2, 2, 1, -1, -2, -2, -1};
public int minKnightMoves(int x, int y) {
if (x == 0 && y == 0) {
return 0;
}
Queue<int[]> que = new ArrayDeque<>();
boolean[][] visited = new boolean[601][601];
que.offer(new int[]{0, 0});
visited[300][300] = true;
int step = 0;
while (!que.isEmpty()) {
int size = que.size();
step++;
while (size-- > 0) {
int[] curr = que.poll();
// y = curr[0], x = curr[1]
for (int i = 0; i < 8; i++) {
int ny = curr[0] + dy[i];
int nx = curr[1] + dx[i];
if (nx == x && ny == y) {
return step;
}
if (visited[ny + 300][nx + 300]) {
continue;
}
que.offer(new int[]{ny, nx});
visited[ny + 300][nx + 300] = true;
}
}
}
return -1;
}
}
Version #2 Bidirectional BFS
这里只是记录这种bidirectional的思路
实际写的时候visited array的boundary和offsite都非常tricky, 写错了好几次
如果不用visited array而用hash成string的方法就会TLE
所以问题很多
Time 和 Space complexity都和上面是一样的
class Solution {
private int[] dx = new int[]{2, 1, -1, -2, -2, -1, 1, 2};
private int[] dy = new int[]{1, 2, 2, 1, -1, -2, -2, -1};
private String hash(int[] grid) {
return grid[0] + "," + grid[1];
}
private int offsite = 600;
public int minKnightMoves(int x, int y) {
if (x == 0 && y == 0) {
return 0;
}
// Bidirectional BFS
// Search from both start point and the end point
int bound = 1201;
int[][] sourceVisited = new int[bound][bound];
int[][] targetVisited = new int[bound][bound];
for (int i = 0; i < bound; i++) {
for (int j = 0; j < bound; j++) {
sourceVisited[i][j] = -1;
targetVisited[i][j] = -1;
}
}
Queue<int[]> sourceQue = new ArrayDeque<>();
sourceVisited[offsite][offsite] = 0;
sourceQue.offer(new int[]{0, 0});
Queue<int[]> targetQue = new ArrayDeque<>();
targetVisited[x + offsite][y + offsite] = 0;
targetQue.offer(new int[]{x, y});
// while (!sourceQue.isEmpty() && !targetQue.isEmpty())
// The queue will never be empty since the board is infinite, so we can just use while "true"
while (true) {
int dist = bfs(sourceQue, sourceVisited, targetVisited);
if (dist > 0) {
return dist;
}
dist = bfs(targetQue, targetVisited, sourceVisited);
if (dist > 0) {
return dist;
}
}
}
private int bfs(Queue<int[]> que, int[][] selfVisited, int[][] otherVisited) {
int[] curr = que.poll();
// dist to the next point
int dist = selfVisited[curr[0] + offsite][curr[1] + offsite] + 1;
// System.out.printf("(%d,%d) -> %d", curr[0], curr[1], dist);
for (int i = 0; i < 8; i++) {
int nx = curr[0] + dx[i];
int ny = curr[1] + dy[i];
if (otherVisited[nx + offsite][ny + offsite] != -1) {
return dist + otherVisited[nx + offsite][ny + offsite];
}
if (selfVisited[nx + offsite][ny + offsite] != -1) {
continue;
}
selfVisited[nx + offsite][ny + offsite] = dist;
que.offer(new int[]{nx, ny});
}
return -1;
}
}
No comments:
Post a Comment