1197. Minimum Knight Moves
In an infinite chess board with coordinates from -infinity
to +infinity
, you have a knight at square [0, 0]
.
A knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal direction, then one square in an orthogonal direction.

Return the minimum number of steps needed to move the knight to the square [x, y]
. It is guaranteed the answer exists.
Example 1:
Input: x = 2, y = 1
Output: 1
Explanation: [0, 0] → [2, 1]
Example 2:
Input: x = 5, y = 5
Output: 4
Explanation: [0, 0] → [2, 1] → [4, 2] → [3, 4] → [5, 5]
Constraints:
|x| + |y| <= 300
// BFS
inline int coordinates2id(int r, int c) {
return r * 300 + c;
}
int minKnightMoves(int x, int y) {
if (x == 0 && y == 0) return 0;
vector<pair<int, int> > dirs({{1, 2}, {2, 1}, {2, -1}, {1, -2}, {-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}});
unordered_set<int> visited;
queue<pair<int, int> > q({{0, 0}});
visited.insert(coordinates2id(0, 0));
int res = 0;
while (!q.empty()) {
++res;
for (int k = q.size() - 1; k >= 0; --k) {
auto t = q.front(); q.pop();
int r = t.first, c = t.second;
for (const auto& dir : dirs) {
int new_r = r + dir.first, new_c = c + dir.second;
if (new_r == x && new_c == y) return res;
if (visited.count(coordinates2id(new_r, new_c))) continue;
if (x >= 0 && new_r < -1) continue;
if (x <= 0 && new_r > 1) continue;
if (y >= 0 && new_c < -1) continue;
if (y <= 0 && new_c > 1) continue;
q.push({new_r, new_c});
visited.insert(coordinates2id(new_r, new_c));
}
}
}
return -1; // invalid
}
// Math
int minKnightMoves(int x, int y) { // time: O(1); space: O(1)
// Axis Symmetry
x = abs(x);
y = abs(y);
// Diagonal Symmetry
if (x < y) swap(x, y);
if (x == 1 && y == 0) return 3;
if (x == 2 && y == 2) return 4;
int delta = x - y;
if (y > delta) {
return (int)(delta - 2 * floor((float)(delta - y) / 3));
} else {
return (int)(delta - 2 * floor((delta - y) / 4));
}
}
Last updated
Was this helpful?