Minimum steps to reach target by a Knight | Set 1 (original) (raw)

Given a square chessboard of n x n size, the position of the Knight and the position of a target are given. We need to find out the minimum steps a Knight will take to reach the target position.

**Examples:

**Input:

kNIGHT

Knight

knightPosition: (1, 3) , targetPosition: (5, 0)

**Output: 3
**Explanation: In above diagram Knight takes 3 step to reach
from (1, 3) to (5, 0)
(1, 3) -> (3, 4) -> (4, 2) -> (5, 0)

This problem can be seen as the shortest path in an unweighted graph. Therefore, BFS is an appropriate algorithm to solve this problem.

Steps:

C++ `

#include <bits/stdc++.h> using namespace std;

// structure for storing a cell's data struct cell { int x, y, dis; cell() : x(0), y(0), dis(0) {} cell(int x, int y, int dis) : x(x), y(y), dis(dis) {} };

// Utility method to check if (x, y) is inside the board bool isInside(int x, int y, int n) { return x >= 1 && x <= n && y >= 1 && y <= n; }

// Method to return the minimum steps to reach target int minSteps(int knightPos[], int targetPos[], int n) {

// x and y direction where a knight can move
int dx[] = { -2, -1, 1, 2, -2, -1, 1, 2 };
int dy[] = { -1, -2, -2, -1, 1, 2, 2, 1 };

// queue for storing knight's states
queue<cell> q;

// push starting position of knight with 0 distance
q.push(cell(knightPos[0], knightPos[1], 0));

cell t;
int x, y;

// Visit array initialized to false
vector<vector<bool>> visit(n + 1, vector<bool>(n + 1, false));

// visit starting position
visit[knightPos[0]][knightPos[1]] = true;

// loop until queue is empty
while (!q.empty()) {
    t = q.front();
    q.pop();

    // if target is reached, return the distance
    if (t.x == targetPos[0] && t.y == targetPos[1])
        return t.dis;

    // explore all reachable positions
    for (int i = 0; i < 8; i++) {
        x = t.x + dx[i];
        y = t.y + dy[i];

        // if the position is valid and not visited, push it to queue
        if (isInside(x, y, n) && !visit[x][y]) {
            visit[x][y] = true;
            q.push(cell(x, y, t.dis + 1));
        }
    }
}

// if no path found, return -1
return -1;

}

int main() { int n = 30; int knightPos[] = { 1, 1 }; int targetPos[] = { 30, 30 }; cout << minSteps(knightPos, targetPos, n); return 0; }

Java

import java.util.*;

// Class to store the cell's data class Cell { int x, y, dis;

// Default constructor
Cell() {
    this.x = 0;
    this.y = 0;
    this.dis = 0;
}

// Parameterized constructor
Cell(int x, int y, int dis) {
    this.x = x;
    this.y = y;
    this.dis = dis;
}

}

public class Solution {

// Utility method to check if (x, y) is inside the board
static boolean isInside(int x, int y, int n) {
    return x >= 1 && x <= n && y >= 1 && y <= n;
}

// Method to return the minimum steps to reach target
static int minSteps(int[] knightPos, int[] targetPos, int n) {
    
    // x and y direction where a knight can move
    int[] dx = { -2, -1, 1, 2, -2, -1, 1, 2 };
    int[] dy = { -1, -2, -2, -1, 1, 2, 2, 1 };

    // Queue for storing knight's states
    Queue<Cell> q = new LinkedList<>();

    // Push starting position of knight with 0 distance
    q.add(new Cell(knightPos[0], knightPos[1], 0));

    Cell t;
    int x, y;

    // Visit array initialized to false
    boolean[][] visit = new boolean[n + 1][n + 1];

    // Visit starting position
    visit[knightPos[0]][knightPos[1]] = true;

    // Loop until queue is empty
    while (!q.isEmpty()) {
        t = q.poll();

        // If target is reached, return the distance
        if (t.x == targetPos[0] && t.y == targetPos[1])
            return t.dis;

        // Explore all reachable positions
        for (int i = 0; i < 8; i++) {
            x = t.x + dx[i];
            y = t.y + dy[i];

            // If the position is valid and not visited, 
            // push it to the queue
            if (isInside(x, y, n) && !visit[x][y]) {
                visit[x][y] = true;
                q.add(new Cell(x, y, t.dis + 1));
            }
        }
    }

    // If no path found, return -1
    return -1;
}

// Driver code
public static void main(String[] args) {
    int n = 30;
    int[] knightPos = { 1, 1 };
    int[] targetPos = { 30, 30 };
    System.out.println(minSteps(knightPos, targetPos, n));
}

}

Python

structure for storing a cell's data

class Cell: def init(self, x=0, y=0, dis=0): self.x = x self.y = y self.dis = dis

Utility method to check if (x, y) is inside the board

def isInside(x, y, n): return 1 <= x <= n and 1 <= y <= n

Method to return the minimum steps to reach target

def minSteps(knightPos, targetPos, n): # x and y direction where a knight can move dx = [-2, -1, 1, 2, -2, -1, 1, 2] dy = [-1, -2, -2, -1, 1, 2, 2, 1]

# queue for storing knight's states
q = []

# push starting position of knight with 0 distance
q.append(Cell(knightPos[0], knightPos[1], 0))

visit = [[False] * (n + 1) for _ in range(n + 1)]

# visit starting position
visit[knightPos[0]][knightPos[1]] = True

# loop until queue is empty
while q:
    t = q.pop(0)

    # if target is reached, return the distance
    if t.x == targetPos[0] and t.y == targetPos[1]:
        return t.dis

    # explore all reachable positions
    for i in range(8):
        x = t.x + dx[i]
        y = t.y + dy[i]

        # if the position is valid and not visited, push it to queue
        if isInside(x, y, n) and not visit[x][y]:
            visit[x][y] = True
            q.append(Cell(x, y, t.dis + 1))

# if no path found, return -1
return -1

Driver code

if name == 'main': n = 30 knightPos = [1, 1] targetPos = [30, 30] print(minSteps(knightPos, targetPos, n))

C#

using System; using System.Collections.Generic;

// Class to store a cell's data class Cell { public int x, y, dis; public Cell() { x = 0; y = 0; dis = 0; } // Default constructor public Cell(int x, int y, int dis) { this.x = x; this.y = y; this.dis = dis; } }

class Solution { // Utility method to check if (x, y) is inside the board static bool IsInside(int x, int y, int n) { return x >= 1 && x <= n && y >= 1 && y <= n; }

// Method to return the minimum steps to reach target
static int MinSteps(int[] knightPos, int[] targetPos, int n)
{
    // x and y directions where a knight can move
    int[] dx = { -2, -1, 1, 2, -2, -1, 1, 2 };
    int[] dy = { -1, -2, -2, -1, 1, 2, 2, 1 };

    // Queue for storing knight's states
    Queue<Cell> q = new Queue<Cell>();

    // Push starting position of knight with 0 distance
    q.Enqueue(new Cell(knightPos[0], knightPos[1], 0));

    Cell t;
    int x, y;

    // Visit array initialized to false
    bool[,] visit = new bool[n + 1, n + 1];

    // Visit starting position
    visit[knightPos[0], knightPos[1]] = true;

    // Loop until queue is empty
    while (q.Count > 0)
    {
        t = q.Dequeue();

        // If target is reached, return the distance
        if (t.x == targetPos[0] && t.y == targetPos[1])
            return t.dis;

        // Explore all reachable positions
        for (int i = 0; i < 8; i++)
        {
            x = t.x + dx[i];
            y = t.y + dy[i];

            // If the position is valid and not visited, push it to queue
            if (IsInside(x, y, n) && !visit[x, y])
            {
                visit[x, y] = true;
                q.Enqueue(new Cell(x, y, t.dis + 1));
            }
        }
    }

    // If no path found, return -1
    return -1;
}

// Driver code
static void Main()
{
    int n = 30;
    int[] knightPos = { 1, 1 };
    int[] targetPos = { 30, 30 };
    Console.WriteLine(MinSteps(knightPos, targetPos, n));
}

}

JavaScript

// structure for storing a cell's data class Cell { constructor(x, y, dis) { this.x = x; this.y = y; this.dis = dis; } }

// Utility method to check if (x, y) is inside the board function isInside(x, y, n) { return x >= 1 && x <= n && y >= 1 && y <= n; }

// Method to return the minimum steps to reach target function minSteps(knightPos, targetPos, n) { // x and y direction where a knight can move const dx = [-2, -1, 1, 2, -2, -1, 1, 2]; const dy = [-1, -2, -2, -1, 1, 2, 2, 1];

// queue for storing knight's states
const q = [];

// push starting position of knight with 0 distance
q.push(new Cell(knightPos[0], knightPos[1], 0));

let t;
let x, y;

// Visit array initialized to false
const visit = Array.from({ length: n + 1 }, () => Array(n + 1).fill(false));

// visit starting position
visit[knightPos[0]][knightPos[1]] = true;

// loop until queue is empty
while (q.length > 0) {
    t = q.shift();

    // if target is reached, return the distance
    if (t.x === targetPos[0] && t.y === targetPos[1])
        return t.dis;

    // explore all reachable positions
    for (let i = 0; i < 8; i++) {
        x = t.x + dx[i];
        y = t.y + dy[i];

        // if the position is valid and not visited, push it to queue
        if (isInside(x, y, n) && !visit[x][y]) {
            visit[x][y] = true;
            q.push(new Cell(x, y, t.dis + 1));
        }
    }
}

// if no path found, return -1
return -1;

}

// Driver code const n = 30; const knightPos = [1, 1]; const targetPos = [30, 30]; console.log(minSteps(knightPos, targetPos, n));

`

**Time complexity: O(n2)
**Auxiliary Space: O(n2)

**Related Articles:

Minimum steps to reach target by a Knight | Set 2