Minimum Knight Moves

medium graph bfs

Problem

On an infinite chessboard, a knight starts at (0, 0) and may move in any of the 8 L-shaped directions. Return the minimum number of moves to reach (x, y).

Inputx = 2, y = 1
Output1
A knight can move directly from (0,0) to (2,1) in one L-shape jump.

from collections import deque

def min_knight_moves(x, y):
    x, y = abs(x), abs(y)
    dirs = [(1,2),(2,1),(-1,2),(-2,1),(1,-2),(2,-1),(-1,-2),(-2,-1)]
    seen = {(0, 0)}
    q = deque([(0, 0, 0)])
    while q:
        cx, cy, d = q.popleft()
        if (cx, cy) == (x, y): return d
        for dx, dy in dirs:
            nx, ny = cx + dx, cy + dy
            if (nx, ny) not in seen and nx >= -2 and ny >= -2:
                seen.add((nx, ny))
                q.append((nx, ny, d + 1))
function minKnightMoves(x, y) {
  x = Math.abs(x); y = Math.abs(y);
  const dirs = [[1,2],[2,1],[-1,2],[-2,1],[1,-2],[2,-1],[-1,-2],[-2,-1]];
  const seen = new Set(["0,0"]);
  const q = [[0, 0, 0]];
  while (q.length) {
    const [cx, cy, d] = q.shift();
    if (cx === x && cy === y) return d;
    for (const [dx, dy] of dirs) {
      const nx = cx + dx, ny = cy + dy, k = nx + "," + ny;
      if (!seen.has(k) && nx >= -2 && ny >= -2) {
        seen.add(k); q.push([nx, ny, d + 1]);
      }
    }
  }
}
class Solution {
    public int minKnightMoves(int x, int y) {
        x = Math.abs(x); y = Math.abs(y);
        int[][] dirs = {{1,2},{2,1},{-1,2},{-2,1},{1,-2},{2,-1},{-1,-2},{-2,-1}};
        Set<Long> seen = new HashSet<>();
        seen.add(0L);
        Deque<int[]> q = new ArrayDeque<>();
        q.offer(new int[]{0, 0, 0});
        while (!q.isEmpty()) {
            int[] c = q.poll();
            if (c[0] == x && c[1] == y) return c[2];
            for (int[] d : dirs) {
                int nx = c[0] + d[0], ny = c[1] + d[1];
                long key = (long) nx * 10000 + ny;
                if (!seen.contains(key) && nx >= -2 && ny >= -2) {
                    seen.add(key);
                    q.offer(new int[]{nx, ny, c[2] + 1});
                }
            }
        }
        return -1;
    }
}
int minKnightMoves(int x, int y) {
    x = abs(x); y = abs(y);
    int dirs[8][2] = {{1,2},{2,1},{-1,2},{-2,1},{1,-2},{2,-1},{-1,-2},{-2,-1}};
    set<pair<int,int>> seen{{0,0}};
    queue<tuple<int,int,int>> q;
    q.push({0, 0, 0});
    while (!q.empty()) {
        auto [cx, cy, d] = q.front(); q.pop();
        if (cx == x && cy == y) return d;
        for (auto& dd : dirs) {
            int nx = cx + dd[0], ny = cy + dd[1];
            if (!seen.count({nx, ny}) && nx >= -2 && ny >= -2) {
                seen.insert({nx, ny});
                q.push({nx, ny, d + 1});
            }
        }
    }
    return -1;
}
Time: O(max(|x|,|y|)²) Space: O(max(|x|,|y|)²)