Minimum steps to reach target by a Knight

Last Updated : 31 Aug, 2026

Given a square chessboard of size n × n, the initial position knightPos[] and target position targetPos[] of a Knight are given. Find the minimum number of moves required for the Knight to reach targetPos.

A Knight moves in an L-shape, covering 2 cells in one direction and 1 cell perpendicular to it. From (x, y), it can move to:

  • (x ± 2, y ± 1)
  • (x ± 1, y ± 2)

This gives at most 8 possible moves:

x_y

Note: The positions are given using 1-based indexing.

Examples: 

Input: n = 3, knightPos[] = [3, 3], targetPos[]= [1, 2]
Output: 1
Explanation: Knight takes 1 step to reach from (3, 3) to (1 ,2).

Input: n = 6, knightPos[] = [1, 3], targetPos[] = [5, 1]
Output: 2
Explanation: In above diagram Knight takes 2 step to reach from (1, 3) to (5, 1): (1, 3) -> (3, 2) -> (5, 1)

file
Try It Yourself
redirect icon

[Naive Approach] Recursion and Backtracking - Exponential Time and O(n^2) Auxiliary Space

The idea is to explore all possible paths that the Knight can take from the initial position to the target and find the path requiring the minimum number of steps.

  • From each position, the Knight can make at most 8 moves.
  • We recursively explore every valid move until the target is reached.
  • A visited array is used to avoid revisiting a cell in the current path.
  • After exploring a move, we unmark the cell to allow it in other paths.
C++
#include <bits/stdc++.h>
using namespace std;

int solve(int x, int y, int tx, int ty, int n,
          vector<vector<bool>>& visited) {

    // If target is reached
    if (x == tx && y == ty)
        return 0;

    int ans = INT_MAX;

    // All 8 possible Knight moves
    int dx[] = {2, 2, -2, -2, 1, 1, -1, -1};
    int dy[] = {1, -1, 1, -1, 2, -2, 2, -2};

    for (int i = 0; i < 8; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];

        // Check if the new position is valid and unvisited
        if (nx >= 0 && nx < n && ny >= 0 && ny < n &&
            !visited[nx][ny]) {

            visited[nx][ny] = true;

            int steps = solve(nx, ny, tx, ty, n, visited);

            if (steps != INT_MAX)
                ans = min(ans, 1 + steps);

            // Backtrack
            visited[nx][ny] = false;
        }
    }

    return ans;
}

int minStepToReachTarget(vector<int>& knightPos,
                         vector<int>& targetPos, int n) {

    // Convert 1-based indexing to 0-based indexing
    int x = knightPos[0] - 1;
    int y = knightPos[1] - 1;
    int tx = targetPos[0] - 1;
    int ty = targetPos[1] - 1;

    vector<vector<bool>> visited(n, vector<bool>(n, false));

    visited[x][y] = true;

    return solve(x, y, tx, ty, n, visited);
}

int main() {
    int n = 3;

    vector<int> knightPos = {3, 3};
    vector<int> targetPos = {1, 2};

    cout << minStepToReachTarget(knightPos, targetPos, n);

    return 0;
}
Java
class GFG {

    static int solve(int x, int y, int tx, int ty, int n,
                     boolean[][] visited) {

        // If target is reached
        if (x == tx && y == ty)
            return 0;

        int ans = Integer.MAX_VALUE;

        // All 8 possible Knight moves
        int[] dx = {2, 2, -2, -2, 1, 1, -1, -1};
        int[] dy = {1, -1, 1, -1, 2, -2, 2, -2};

        for (int i = 0; i < 8; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];

            // Check if the new position is valid and unvisited
            if (nx >= 0 && nx < n && ny >= 0 && ny < n &&
                !visited[nx][ny]) {

                visited[nx][ny] = true;

                int steps = solve(nx, ny, tx, ty, n, visited);

                if (steps != Integer.MAX_VALUE)
                    ans = Math.min(ans, 1 + steps);

                // Backtrack
                visited[nx][ny] = false;
            }
        }

        return ans;
    }

    static int minStepToReachTarget(int[] knightPos,
                                    int[] targetPos, int n) {

        // Convert 1-based indexing to 0-based indexing
        int x = knightPos[0] - 1;
        int y = knightPos[1] - 1;
        int tx = targetPos[0] - 1;
        int ty = targetPos[1] - 1;

        boolean[][] visited = new boolean[n][n];

        visited[x][y] = true;

        return solve(x, y, tx, ty, n, visited);
    }

    public static void main(String[] args) {
        int n = 3;

        int[] knightPos = {3, 3};
        int[] targetPos = {1, 2};

        System.out.println(minStepToReachTarget(knightPos, targetPos, n));
    }
}
Python
def solve(x, y, tx, ty, n, visited):

    # If target is reached
    if x == tx and y == ty:
        return 0

    ans = float('inf')

    # All 8 possible Knight moves
    dx = [2, 2, -2, -2, 1, 1, -1, -1]
    dy = [1, -1, 1, -1, 2, -2, 2, -2]

    for i in range(8):
        nx = x + dx[i]
        ny = y + dy[i]

        # Check if the new position is valid and unvisited
        if (nx >= 0 and nx < n and ny >= 0 and ny < n
                and not visited[nx][ny]):

            visited[nx][ny] = True

            steps = solve(nx, ny, tx, ty, n, visited)

            if steps != float('inf'):
                ans = min(ans, 1 + steps)

            # Backtrack
            visited[nx][ny] = False

    return ans


def minStepToReachTarget(knightPos, targetPos, n):

    # Convert 1-based indexing to 0-based indexing
    x = knightPos[0] - 1
    y = knightPos[1] - 1
    tx = targetPos[0] - 1
    ty = targetPos[1] - 1

    visited = [[False for _ in range(n)] for _ in range(n)]

    visited[x][y] = True

    return solve(x, y, tx, ty, n, visited)


if __name__ == "__main__":
    n = 3

    knightPos = [3, 3]
    targetPos = [1, 2]

    print(minStepToReachTarget(knightPos, targetPos, n))
C#
using System;
using System.Collections.Generic;

class GFG
{
    static int solve(int x, int y, int tx, int ty, int n,
                     bool[,] visited)
    {
        // If target is reached
        if (x == tx && y == ty)
            return 0;

        int ans = int.MaxValue;

        // All 8 possible Knight moves
        int[] dx = { 2, 2, -2, -2, 1, 1, -1, -1 };
        int[] dy = { 1, -1, 1, -1, 2, -2, 2, -2 };

        for (int i = 0; i < 8; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];

            // Check if the new position is valid and unvisited
            if (nx >= 0 && nx < n && ny >= 0 && ny < n &&
                !visited[nx, ny])
            {
                visited[nx, ny] = true;

                int steps = solve(nx, ny, tx, ty, n, visited);

                if (steps != int.MaxValue)
                    ans = Math.Min(ans, 1 + steps);

                // Backtrack
                visited[nx, ny] = false;
            }
        }

        return ans;
    }

    static int minStepToReachTarget(int[] knightPos,
                                    int[] targetPos, int n)
    {
        // Convert 1-based indexing to 0-based indexing
        int x = knightPos[0] - 1;
        int y = knightPos[1] - 1;
        int tx = targetPos[0] - 1;
        int ty = targetPos[1] - 1;

        bool[,] visited = new bool[n, n];

        visited[x, y] = true;

        return solve(x, y, tx, ty, n, visited);
    }

    static void Main()
    {
        int n = 3;

        int[] knightPos = { 3, 3 };
        int[] targetPos = { 1, 2 };

        Console.WriteLine(
            minStepToReachTarget(knightPos, targetPos, n)
        );
    }
}
JavaScript
function solve(x, y, tx, ty, n, visited) {

    // If target is reached
    if (x === tx && y === ty)
        return 0;

    let ans = Infinity;

    // All 8 possible Knight moves
    let dx = [2, 2, -2, -2, 1, 1, -1, -1];
    let dy = [1, -1, 1, -1, 2, -2, 2, -2];

    for (let i = 0; i < 8; i++) {
        let nx = x + dx[i];
        let ny = y + dy[i];

        // Check if the new position is valid and unvisited
        if (nx >= 0 && nx < n && ny >= 0 && ny < n &&
            !visited[nx][ny]) {

            visited[nx][ny] = true;

            let steps = solve(nx, ny, tx, ty, n, visited);

            if (steps !== Infinity)
                ans = Math.min(ans, 1 + steps);

            // Backtrack
            visited[nx][ny] = false;
        }
    }

    return ans;
}

function minStepToReachTarget(knightPos, targetPos, n) {

    // Convert 1-based indexing to 0-based indexing
    let x = knightPos[0] - 1;
    let y = knightPos[1] - 1;
    let tx = targetPos[0] - 1;
    let ty = targetPos[1] - 1;

    let visited = Array.from(
        { length: n },
        () => Array(n).fill(false)
    );

    visited[x][y] = true;

    return solve(x, y, tx, ty, n, visited);
}

// Driver code
    let n = 3;

    let knightPos = [3, 3];
    let targetPos = [1, 2];

    console.log(minStepToReachTarget(knightPos, targetPos, n));

Output
1

[Expected Approch] BFS - Shortest Path in O(n^2) Time and O(n^2) Space

The idea is to treat the chessboard as an unweighted graph and use Breadth-First Search (BFS) to find the shortest path from the Knight's initial position to the target position.

We can view the chessboard as a graph:

  • Each cell of the chessboard represents a node.
  • Each valid Knight move represents an edge between two cells.
  • The Knight's initial position is the starting node.
  • The target position is the destination node.
  • Every Knight move takes exactly 1 step, so all edges have the same cost.

Therefore, finding the minimum number of Knight moves is equivalent to finding the shortest path between two nodes in an unweighted graph.

BFS is well suited for this because it explores the graph level by level.

Steps:

  • Convert the starting and target positions from 1-based to 0-based indexing.
  • Add the starting position to the queue with 0 steps and mark it as visited.
  • Remove a position from the queue and check all 8 possible Knight moves.
  • For every valid and unvisited position, mark it as visited and add it to the queue with one more step.
  • If the target position is reached, return the number of steps.
  • If the target cannot be reached, return -1.
C++
#include <bits/stdc++.h>
using namespace std;

int minStepToReachTarget(vector<int>& knightPos,
                         vector<int>& targetPos, int n) {

    // Convert 1-based indexing to 0-based indexing
    int x = knightPos[0] - 1;
    int y = knightPos[1] - 1;
    int tx = targetPos[0] - 1;
    int ty = targetPos[1] - 1;

    // All 8 possible Knight moves
    int dx[] = {2, 2, -2, -2, 1, 1, -1, -1};
    int dy[] = {1, -1, 1, -1, 2, -2, 2, -2};

    // Queue stores position and number of steps
    queue<pair<pair<int, int>, int>> q;

    // Mark visited cells
    vector<vector<bool>> visited(n, vector<bool>(n, false));

    // Start BFS from the initial position
    q.push({{x, y}, 0});
    visited[x][y] = true;

    while (!q.empty()) {
        int x = q.front().first.first;
        int y = q.front().first.second;
        int steps = q.front().second;

        q.pop();

        // If target is reached
        if (x == tx && y == ty)
            return steps;

        // Try all 8 possible Knight moves
        for (int i = 0; i < 8; i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];

            // Check if the new position is valid and unvisited
            if (nx >= 0 && nx < n && ny >= 0 && ny < n &&
                !visited[nx][ny]) {

                visited[nx][ny] = true;

                // Add the new position with updated steps
                q.push({{nx, ny}, steps + 1});
            }
        }
    }

    return -1;
}

int main() {
    int n = 6;

    vector<int> knightPos = {4, 5};
    vector<int> targetPos = {1, 1};

    cout << minStepToReachTarget(knightPos, targetPos, n);

    return 0;
}
Java
import java.util.Queue;
import java.util.LinkedList;

class GFG {

    static int minStepToReachTarget(int[] knightPos,
                                    int[] targetPos, int n) {

        // Convert 1-based indexing to 0-based indexing
        int x = knightPos[0] - 1;
        int y = knightPos[1] - 1;
        int tx = targetPos[0] - 1;
        int ty = targetPos[1] - 1;

        // All 8 possible Knight moves
        int[] dx = {2, 2, -2, -2, 1, 1, -1, -1};
        int[] dy = {1, -1, 1, -1, 2, -2, 2, -2};

        // Queue stores position and number of steps
        Queue<int[]> q = new LinkedList<>();

        // Mark visited cells
        boolean[][] visited = new boolean[n][n];

        // Start BFS from the initial position
        q.offer(new int[]{x, y, 0});
        visited[x][y] = true;

        while (!q.isEmpty()) {
            int[] curr = q.poll();

            x = curr[0];
            y = curr[1];
            int steps = curr[2];

            // If target is reached
            if (x == tx && y == ty)
                return steps;

            // Try all 8 possible Knight moves
            for (int i = 0; i < 8; i++) {
                int nx = x + dx[i];
                int ny = y + dy[i];

                // Check if the new position is valid and unvisited
                if (nx >= 0 && nx < n && ny >= 0 && ny < n &&
                    !visited[nx][ny]) {

                    visited[nx][ny] = true;

                    // Add the new position with updated steps
                    q.offer(new int[]{nx, ny, steps + 1});
                }
            }
        }

        return -1;
    }

    public static void main(String[] args) {
        int n = 6;

        int[] knightPos = {4, 5};
        int[] targetPos = {1, 1};

        System.out.println(
            minStepToReachTarget(knightPos, targetPos, n)
        );
    }
}
Python
from collections import deque

def minStepToReachTarget(knightPos, targetPos, n):

    # Convert 1-based indexing to 0-based indexing
    x = knightPos[0] - 1
    y = knightPos[1] - 1
    tx = targetPos[0] - 1
    ty = targetPos[1] - 1

    # All 8 possible Knight moves
    dx = [2, 2, -2, -2, 1, 1, -1, -1]
    dy = [1, -1, 1, -1, 2, -2, 2, -2]

    # Queue stores position and number of steps
    q = deque()

    # Mark visited cells
    visited = [[False] * n for _ in range(n)]

    # Start BFS from the initial position
    q.append((x, y, 0))
    visited[x][y] = True

    while q:
        x, y, steps = q.popleft()

        # If target is reached
        if x == tx and y == ty:
            return steps

        # Try all 8 possible Knight moves
        for i in range(8):
            nx = x + dx[i]
            ny = y + dy[i]

            # Check if the new position is valid and unvisited
            if (nx >= 0 and nx < n and ny >= 0 and ny < n
                    and not visited[nx][ny]):

                visited[nx][ny] = True

                # Add the new position with updated steps
                q.append((nx, ny, steps + 1))

    return -1


if __name__ == "__main__":
    n = 6

    knightPos = [4, 5]
    targetPos = [1, 1]

    print(minStepToReachTarget(knightPos, targetPos, n))
C#
using System;
using System.Collections.Generic;

class GFG
{
    static int minStepToReachTarget(int[] knightPos,
                                    int[] targetPos, int n)
    {
        // Convert 1-based indexing to 0-based indexing
        int x = knightPos[0] - 1;
        int y = knightPos[1] - 1;
        int tx = targetPos[0] - 1;
        int ty = targetPos[1] - 1;

        // All 8 possible Knight moves
        int[] dx = { 2, 2, -2, -2, 1, 1, -1, -1 };
        int[] dy = { 1, -1, 1, -1, 2, -2, 2, -2 };

        // Queue stores position and number of steps
        Queue<int[]> q = new Queue<int[]>();

        // Mark visited cells
        bool[,] visited = new bool[n, n];

        // Start BFS from the initial position
        q.Enqueue(new int[] { x, y, 0 });
        visited[x, y] = true;

        while (q.Count > 0)
        {
            int[] curr = q.Dequeue();

            x = curr[0];
            y = curr[1];
            int steps = curr[2];

            // If target is reached
            if (x == tx && y == ty)
                return steps;

            // Try all 8 possible Knight moves
            for (int i = 0; i < 8; i++)
            {
                int nx = x + dx[i];
                int ny = y + dy[i];

                // Check if the new position is valid and unvisited
                if (nx >= 0 && nx < n && ny >= 0 && ny < n &&
                    !visited[nx, ny])
                {
                    visited[nx, ny] = true;

                    // Add the new position with updated steps
                    q.Enqueue(new int[] { nx, ny, steps + 1 });
                }
            }
        }

        return -1;
    }

    static void Main()
    {
        int n = 6;

        int[] knightPos = { 4, 5 };
        int[] targetPos = { 1, 1 };

        Console.WriteLine(
            minStepToReachTarget(knightPos, targetPos, n)
        );
    }
}
JavaScript
function minStepToReachTarget(knightPos, targetPos, n)
{

    // Convert 1-based indexing to 0-based indexing
    let x = knightPos[0] - 1;
    let y = knightPos[1] - 1;
    let tx = targetPos[0] - 1;
    let ty = targetPos[1] - 1;

    // All 8 possible Knight moves
    let dx = [ 2, 2, -2, -2, 1, 1, -1, -1 ];
    let dy = [ 1, -1, 1, -1, 2, -2, 2, -2 ];

    // Queue stores position and number of steps
    let q = [];

    // Mark visited cells
    let visited = Array.from({length : n},
                             () => Array(n).fill(false));

    // Start BFS from the initial position
    q.push([ x, y, 0 ]);
    visited[x][y] = true;

    let front = 0;

    while (front < q.length) {
        let curr = q[front++];

        x = curr[0];
        y = curr[1];
        let steps = curr[2];

        // If target is reached
        if (x === tx && y === ty)
            return steps;

        // Try all 8 possible Knight moves
        for (let i = 0; i < 8; i++) {
            let nx = x + dx[i];
            let ny = y + dy[i];

            // Check if the new position is valid and
            // unvisited
            if (nx >= 0 && nx < n && ny >= 0 && ny < n
                && !visited[nx][ny]) {

                visited[nx][ny] = true;

                // Add the new position with updated steps
                q.push([ nx, ny, steps + 1 ]);
            }
        }
    }

    return -1;
}

// Driver code
let n = 6;

let knightPos = [ 4, 5 ];
let targetPos = [ 1, 1 ];

console.log(minStepToReachTarget(knightPos, targetPos, n));

Output
3
Comment