The Knight's Tour (original) (raw)

Last Updated : 29 Sep, 2025

Given an integer **n, consider an n × n chessboard. A Knight starts at the top-left corner (0, 0) and must visit **every cell exactly once following the Knight’s standard moves in chess (two steps in one direction and one step perpendicular).

**Examples:

**Input: n = 5
**Output:
[[0, 5, 14, 9, 20],
[13, 8, 19, 4, 15],
[18, 1, 6, 21, 10],
[7, 12, 23, 16, 3],
[24, 17, 2, 11, 22]]
**Explanation: Each number represents the step at which the Knight visits that cell, starting from (0, 0) as step 0. The output shows one valid Knight’s Tour on a 5×5 board.

**Input: n = 3
**Output: [-1]
**Explanation: It is not possible to find a valid Knight's Tour on a 3x3 chessboard since the Knight cannot visit all 9 cells exactly once without revisiting or getting stuck.

Try It Yourselfredirect icon

Table of Content

[Approach -1] Using Recursion + Backtracking - O(8n*n) Time and O(n2) Space

We will use recursion and backtracking to build a sequence of knight moves that visits every cell once. Start at (0, 0), mark each visited cell with the move number, and try all 8 knight moves from the current cell. If a move leads to a dead end, undo it (backtrack) and try the next move. Stop when you have placed n*n moves (success) or exhausted all options (failure).

C++ `

#include #include using namespace std;

// 8 directions of knight moves int dx[8] = {2, 1, -1, -2, -2, -1, 1, 2}; int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};

// Utility function to check if the // move is valid bool isSafe(int x, int y, int n, vector<vector> &board) { return (x >= 0 && y >= 0 && x < n && y < n && board[x][y] == -1); }

// Recursive function to solve Knight's Tour bool knightTourUtil(int x, int y, int step, int n, vector<vector> &board) {

// If all squares are visited
if (step == n * n) {
    return true;
}

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

    if (isSafe(nx, ny, n, board)) {
        board[nx][ny] = step;

        if (knightTourUtil(nx, ny, step + 1, n, board)) {
            return true;
        }

        // Backtrack
        board[nx][ny] = -1;
    }
}

return false;

}

// Function to start Knight's Tour vector<vector> knightTour(int n) { vector<vector> board(n, vector(n, -1));

// Start from top-left corner
board[0][0] = 0;

if (knightTourUtil(0, 0, 1, n, board)) {
    return board;
}

return {{-1}};

}

int main() { int n = 5;

vector<vector<int>> res = knightTour(n);

for (auto &row : res) {
    for (int val : row) {
        cout << val << " ";
    }
    cout << endl;
}

return 0;

}

Java

import java.util.ArrayList; import java.util.Arrays;

class GFG {

// 8 directions of knight moves
static int[] dx = {2, 1, -1, -2, -2, -1, 1, 2};
static int[] dy = {1, 2, 2, 1, -1, -2, -2, -1};

// Utility function to check if the 
// move is valid
static boolean isSafe(int x, int y, int n, ArrayList<ArrayList<Integer>> board) {
    return (x >= 0 && y >= 0 && x < n &&
            y < n && board.get(x).get(y) == -1);
}

// Recursive function to solve Knight's Tour
static boolean knightTourUtil(int x, int y, int step, int n,
                               ArrayList<ArrayList<Integer>> board) {

    // If all squares are visited
    if (step == n * n) {
        return true;
    }

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

        if (isSafe(nx, ny, n, board)) {
            board.get(nx).set(ny, step);

            if (knightTourUtil(nx, ny, step + 1, n, board)) {
                return true;
            }

            // Backtrack
            board.get(nx).set(ny, -1);
        }
    }

    return false;
}

// Function to start Knight's Tour
static ArrayList<ArrayList<Integer>> knightTour(int n) {
    ArrayList<ArrayList<Integer>> board = new ArrayList<>();

    for (int i = 0; i < n; i++) {
        ArrayList<Integer> row = new ArrayList<>();
        for (int j = 0; j < n; j++) {
            row.add(-1);
        }
        board.add(row);
    }

    // Start from top-left corner
    board.get(0).set(0, 0);

    if (knightTourUtil(0, 0, 1, n, board)) {
        return board;
    }

    // If no solution exists, return board with -1 only
    ArrayList<ArrayList<Integer>> noSol = new ArrayList<>();
    ArrayList<Integer> row = new ArrayList<>();
    row.add(-1);
    noSol.add(row);
    return noSol;
}

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

    ArrayList<ArrayList<Integer>> res = knightTour(n);

    for (ArrayList<Integer> row : res) {
        for (int val : row) {
            System.out.print(val + " ");
        }
        System.out.println();
    }
}

}

Python

dx = [2, 1, -1, -2, -2, -1, 1, 2] dy = [1, 2, 2, 1, -1, -2, -2, -1]

def isSafe(x, y, n, board): return x >= 0 and y >= 0 and x < n and y < n and board[x][y] == -1

def knightTourUtil(x, y, step, n, board): # If all squares are visited if step == n * n: return True

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

    if isSafe(nx, ny, n, board):
        board[nx][ny] = step

        if knightTourUtil(nx, ny, step + 1, n, board):
            return True

        # Backtrack
        board[nx][ny] = -1

return False

def knightTour(n): board = [[-1 for _ in range(n)] for _ in range(n)]

# Start from top-left corner
board[0][0] = 0

if knightTourUtil(0, 0, 1, n, board):
    return board

return [[-1]]

if name=="main": n = 5 res = knightTour(n)

for row in res:
    for val in row:
        print(val, end=" ")
    print()

C#

using System; using System.Collections.Generic;

class GFG { static int[] dx = { 2, 1, -1, -2, -2, -1, 1, 2 }; static int[] dy = { 1, 2, 2, 1, -1, -2, -2, -1 };

static bool isSafe(int x, int y, int n, List<List<int>> board) {
    return x >= 0 && y >= 0 && x < n && y < n && board[x][y] == -1;
}

static bool knightTourUtil(int x, int y, int step, int n, List<List<int>> board) {
    
    // If all squares are visited
    if (step == n * n)
        return true;

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

        if (isSafe(nx, ny, n, board)) {
            board[nx][ny] = step;

            if (knightTourUtil(nx, ny, step + 1, n, board))
                return true;

            // Backtrack
            board[nx][ny] = -1;
        }
    }
    return false;
}

static List<List<int>> knightTour(int n) {
    var board = new List<List<int>>();
    for (int i = 0; i < n; i++) {
        var row = new List<int>();
        for (int j = 0; j < n; j++)
            row.Add(-1);
        board.Add(row);
    }

    // Start from top-left corner
    board[0][0] = 0;

    if (knightTourUtil(0, 0, 1, n, board))
        return board;

    return new List<List<int>> { new List<int> { -1 } };
}

static void Main() {
    int n = 5;
    var res = knightTour(n);

    foreach (var row in res) {
        foreach (var val in row)
            Console.Write(val + " ");
        Console.WriteLine();
    }
}

}

JavaScript

// 8 possible knight moves const dx = [2, 1, -1, -2, -2, -1, 1, 2]; const dy = [1, 2, 2, 1, -1, -2, -2, -1];

// Check if a cell is valid function isSafe(x, y, n, board) { return x >= 0 && y >= 0 && x < n && y < n && board[x][y] === -1; }

// Recursive utility function for Knight's Tour function knightTourUtil(x, y, step, n, board) { if (step === n * n) return true;

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

    if (isSafe(nx, ny, n, board)) {
        board[nx][ny] = step;

        if (knightTourUtil(nx, ny, step + 1, n, board)) return true;

        // Backtrack
        board[nx][ny] = -1;
    }
}
return false;

}

// Function to start Knight's Tour function knightTour(n) { const board = Array.from({ length: n }, () => Array(n).fill(-1));

// Start from top-left corner
board[0][0] = 0;

if (knightTourUtil(0, 0, 1, n, board)) return board;

return [[-1]];

}

// Driver code const n = 5; const res = knightTour(n);

for (const row of res) { console.log(row.join(' ')); }

`

Output

0 5 14 9 20 13 8 19 4 15 18 1 6 21 10 7 12 23 16 3 24 17 2 11 22

[Approach -2] Using Warnsdorff's Algorithm - O(n3) Time and O(n2) Space

When solving the Knight's Tour problem, backtracking works but is inefficient because it explores many unnecessary paths. If the correct move happens to be the last option, the algorithm wastes time trying all the wrong ones first.

A smarter strategy is Warnsdorff’s Algorithm, which uses a heuristic to reduce backtracking. Instead of trying moves in random order, it always chooses the next move with the fewest onward moves (the cell with the smallest degree). This prevents the knight from getting stuck early and greatly improves efficiency.

**Illustration

ezg3

C++ `

#include #include #include using namespace std;

// Define 8 knight moves globally int dir[8][2] = { {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1} };

// Count the number of onward moves from position (x, y) int countOptions(vector<vector>& board, int x, int y) { int count = 0; int n = board.size();

for (int i = 0; i < 8; i++) {
    int nx = x + dir[i][0];
    int ny = y + dir[i][1];
    if (nx >= 0 && ny >= 0 && nx < n && ny < n && board[nx][ny] == -1) {
        count++;
    }
}
return count;

}

// Generate valid knight moves from (x, y), sorted by fewest onward moves vector<vector> getSortedMoves(vector<vector>& board, int x, int y) { vector<vector> moveList;

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

    if (nx >= 0 && ny >= 0 && nx < board.size() && ny < board.size() &&
        board[nx][ny] == -1) {
        int options = countOptions(board, nx, ny);
        moveList.push_back({options, i});
    }
}

// Sort using default vector<int> lexicographic comparison
sort(moveList.begin(), moveList.end());

return moveList;

}

// Recursive function to solve the Knight's Tour bool knightTourUtil(int x, int y, int step, int n, vector<vector>& board) { if (step == n * n) return true;

vector<vector<int>> moves = getSortedMoves(board, x, y);

for (vector<int> move : moves) {
    int dirIdx = move[1];
    int nx = x + dir[dirIdx][0];
    int ny = y + dir[dirIdx][1];

    board[nx][ny] = step;
    if (knightTourUtil(nx, ny, step + 1, n, board))
        return true;

    // Backtrack
    board[nx][ny] = -1;
}
return false;

}

// Function to start Knight's Tour vector<vector> knightTour(int n) { vector<vector> board(n, vector(n, -1));

// Start from top-left corner
board[0][0] = 0;

if (knightTourUtil(0, 0, 1, n, board)) {
    return board;
}

return {{-1}};

}

int main() { int n = 5; vector<vector> result = knightTour(n);

for (vector<int> row : result) {
    for (int val : row) {
        cout << val << " ";
    }
    cout << endl;
}

return 0;

}

Java

import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator;

class GFG {

// Define 8 knight moves globally
static int[][] dir = {
    {2, 1}, {1, 2}, {-1, 2}, {-2, 1},
    {-2, -1}, {-1, -2}, {1, -2}, {2, -1}
};

// Count the number of onward moves from position (x, y)
static int countOptions(ArrayList<ArrayList<Integer>> board, 
                                                    int x, int y) {
    int count = 0, n = board.size();
    for (int i = 0; i < 8; i++) {
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        if (nx >= 0 && ny >= 0 && nx < n && ny < n
                        && board.get(nx).get(ny) == -1)
            count++;
    }
    return count;
}

// Generate valid knight moves from (x, y), sorted by fewest onward moves
static ArrayList<ArrayList<Integer>> getSortedMoves(
            ArrayList<ArrayList<Integer>> board, int x, int y) {
    
    ArrayList<ArrayList<Integer>> moveList = new ArrayList<>();
    int n = board.size();

    for (int i = 0; i < 8; i++) {
        int nx = x + dir[i][0];
        int ny = y + dir[i][1];
        if (nx >= 0 && ny >= 0 && nx < n && ny < n &&
                            board.get(nx).get(ny) == -1) {
            
            int options = countOptions(board, nx, ny);
            ArrayList<Integer> move = new ArrayList<>();
            move.add(options);
            move.add(i);
            moveList.add(move);
        }
    }

    // Sort by options count
    Collections.sort(moveList, new Comparator<ArrayList<Integer>>() {
        public int compare(ArrayList<Integer> a, ArrayList<Integer> b) {
            if (!a.get(0).equals(b.get(0))) return a.get(0) - b.get(0);
            return a.get(1) - b.get(1);
        }
    });

    return moveList;
}

// Recursive function to solve the Knight's Tour
static boolean knightTourUtil(int x, int y, int step, int n,
                            ArrayList<ArrayList<Integer>> board) {
    if (step == n * n) return true;

    ArrayList<ArrayList<Integer>> moves = getSortedMoves(board, x, y);

    for (ArrayList<Integer> move : moves) {
        int dirIdx = move.get(1);
        int nx = x + dir[dirIdx][0];
        int ny = y + dir[dirIdx][1];

        board.get(nx).set(ny, step);
        if (knightTourUtil(nx, ny, step + 1, n, board))
            return true;

        // Backtrack
        board.get(nx).set(ny, -1);
    }
    return false;
}

// Function to start Knight's Tour
static ArrayList<ArrayList<Integer>> knightTour(int n) {
    ArrayList<ArrayList<Integer>> board = new ArrayList<>();
    for (int i = 0; i < n; i++) {
        ArrayList<Integer> row = new ArrayList<>(Collections.nCopies(n, -1));
        board.add(row);
    }

    board.get(0).set(0, 0);
    if (knightTourUtil(0, 0, 1, n, board))
        return board;

    ArrayList<ArrayList<Integer>> fail = new ArrayList<>();
    fail.add(new ArrayList<>(Arrays.asList(-1)));
    return fail;
}

public static void main(String[] args) {
    int n = 5;
    ArrayList<ArrayList<Integer>> result = knightTour(n);

    for (ArrayList<Integer> row : result) {
        for (int val : row)
            System.out.print(val + " ");
        System.out.println();
    }
}

}

Python

Define 8 knight moves globally

dir = [ [2, 1], [1, 2], [-1, 2], [-2, 1], [-2, -1], [-1, -2], [1, -2], [2, -1] ]

Count the number of onward moves from position (x, y)

def countOptions(board, x, y): count, n = 0, len(board) for dx, dy in dir: nx, ny = x + dx, y + dy if 0 <= nx < n and 0 <= ny < n and board[nx][ny] == -1: count += 1 return count

Generate valid knight moves from (x, y), sorted by fewest onward moves

def getSortedMoves(board, x, y): moveList, n = [], len(board) for i in range(8): nx, ny = x + dir[i][0], y + dir[i][1] if 0 <= nx < n and 0 <= ny < n and board[nx][ny] == -1: options = countOptions(board, nx, ny) moveList.append([options, i]) moveList.sort() return moveList

Recursive function to solve the Knight's Tour

def knightTourUtil(x, y, step, n, board): if step == n * n: return True moves = getSortedMoves(board, x, y) for move in moves: dirIdx = move[1] nx, ny = x + dir[dirIdx][0], y + dir[dirIdx][1] board[nx][ny] = step if knightTourUtil(nx, ny, step + 1, n, board): return True

    # Backtrack
    board[nx][ny] = -1
return False

Function to start Knight's Tour

def knightTour(n): board = [[-1]*n for _ in range(n)] board[0][0] = 0 if knightTourUtil(0, 0, 1, n, board): return board return [[-1]]

if name == 'main': n = 5 result = knightTour(n) for row in result: print(*row)

C#

using System; using System.Collections.Generic;

class GFG {

// Define 8 knight moves globally
static int[,] dir = {
    {2, 1}, {1, 2}, {-1, 2}, {-2, 1},
    {-2, -1}, {-1, -2}, {1, -2}, {2, -1}
};

// Count the number of onward moves from position (x, y)
static int countOptions(int[,] board, int x, int y) {
    int count = 0, n = board.GetLength(0);
    for (int i = 0; i < 8; i++) {
        int nx = x + dir[i, 0];
        int ny = y + dir[i, 1];
        if (nx >= 0 && ny >= 0 && nx < n && ny < n && board[nx, ny] == -1)
            count++;
    }
    return count;
}

// Generate valid knight moves from (x, y), sorted by fewest onward moves
static List<int[]> getSortedMoves(int[,] board, int x, int y) {
    List<int[]> moveList = new List<int[]>();
    int n = board.GetLength(0);

    for (int i = 0; i < 8; i++) {
        int nx = x + dir[i, 0];
        int ny = y + dir[i, 1];
        if (nx >= 0 && ny >= 0 && nx < n && ny < n && board[nx, ny] == -1) {
            int options = countOptions(board, nx, ny);
            moveList.Add(new int[]{options, i});
        }
    }

    moveList.Sort((a, b) => a[0] != b[0] ?
            a[0].CompareTo(b[0]) : a[1].CompareTo(b[1]));
    return moveList;
}

// Recursive function to solve the Knight's Tour
static bool knightTourUtil(int x, int y, int step, int n, int[,] board) {
    if (step == n * n) return true;

    List<int[]> moves = getSortedMoves(board, x, y);

    foreach (var move in moves) {
        int dirIdx = move[1];
        int nx = x + dir[dirIdx, 0];
        int ny = y + dir[dirIdx, 1];

        board[nx, ny] = step;
        if (knightTourUtil(nx, ny, step + 1, n, board))
            return true;

        // Backtrack
        board[nx, ny] = -1;
    }
    return false;
}

// Function to start Knight's Tour
static List<List<int>> knightTour(int n) {
    int[,] board = new int[n, n];
    List<List<int>> res = new List<List<int>>();
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            board[i, j] = -1;

    board[0, 0] = 0;
    if (knightTourUtil(0, 0, 1, n, board)) {
        for (int i = 0; i < n; i++) {
            List<int> rowList = new List<int>();
            for (int j = 0; j < n; j++)
                rowList.Add(board[i, j]);
            res.Add(rowList);
        }
        return res;
    }

    res.Add(new List<int>{-1});
    return res;
}

public static void Main() {
    int n = 5;
    List<List<int>> result = knightTour(n);

    foreach (var row in result) {
        Console.WriteLine(string.Join(" ", row));
    }
}

}

JavaScript

// Define 8 knight moves globally let dir = [ [2, 1], [1, 2], [-1, 2], [-2, 1], [-2, -1], [-1, -2], [1, -2], [2, -1] ];

// Count the number of onward moves from position (x, y) function countOptions(board, x, y) { let count = 0, n = board.length; for (let i = 0; i < 8; i++) { let nx = x + dir[i][0]; let ny = y + dir[i][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n && board[nx][ny] === -1) count++; } return count; }

// Generate valid knight moves from (x, y), sorted by fewest onward moves function getSortedMoves(board, x, y) { let moveList = [], n = board.length; for (let i = 0; i < 8; i++) { let nx = x + dir[i][0]; let ny = y + dir[i][1]; if (nx >= 0 && ny >= 0 && nx < n && ny < n && board[nx][ny] === -1) { let options = countOptions(board, nx, ny); moveList.push([options, i]); } } moveList.sort((a, b) => (a[0] - b[0]) || (a[1] - b[1])); return moveList; }

// Recursive function to solve the Knight's Tour function knightTourUtil(x, y, step, n, board) { if (step === n * n) return true;

let moves = getSortedMoves(board, x, y);

for (let move of moves) { let dirIdx = move[1]; let nx = x + dir[dirIdx][0]; let ny = y + dir[dirIdx][1];

board[nx][ny] = step;
if (knightTourUtil(nx, ny, step + 1, n, board))
  return true;

// Backtrack
board[nx][ny] = -1;

} return false; }

// Function to start Knight's Tour function knightTour(n) { let board = Array.from({ length: n }, () => Array(n).fill(-1)); board[0][0] = 0;

if (knightTourUtil(0, 0, 1, n, board)) return board;

return [[-1]]; }

// Driver Code let n = 5; let result = knightTour(n); for (let row of result) { console.log(row.join(" ")); }

`

Output

0 21 10 15 6 11 16 7 20 9 24 1 22 5 14 17 12 3 8 19 2 23 18 13 4