Knight's Tour

Last Updated : 9 Oct, 2026

Given an integer n, representing the size of an n × n chessboard. A Knight moves two cells in one direction and one cell perpendicular to that direction.

  • Knight starts at the top-left corner (0, 0) of the board.
  • Your task is to find a valid tour, in which the Knight visits every cell of the board exactly once. Return an n × n matrix in which each cell contains the order in which it is visited. 
  • If a valid tour does not exist, return an empty list.  
  • There can be multiple valid tours, you may return any one.

Examples:

Input: n = 5
Output:
[[0, 11, 2, 17, 20],
[3, 16, 19, 12, 7],
[10, 1, 6, 21, 18],
[15, 4, 23, 8, 13],
[24, 9, 14, 5, 22]]
Explanation: A possible knight's tour in a 5 x 5 chessboard is given above where each number represents the step at which the Knight visits that cell, starting from (0, 0) as step 0.

Input: n = 4
Output: []
Explanation: For n = 4, no sequence of knight moves can visit all 16 cells exactly once, starting from the top-left cell. Hence, the answer is an empty array [].

Try It Yourself
redirect icon

Recursion + Backtracking - O(8^(n * n)) Time and O(n^2) Space

The idea is to use recursion and backtracking to find a knight's tour that visits every cell exactly once.

  • Start at (0, 0), mark it as 0, and try all 8 possible knight moves from the current cell.
  • If a move leads to a dead end, undo it (backtrack) and try another move.
  • Stop when all n*n cells are visited or no valid tour exists.
  • Initialize an n × n board with -1 and mark the top-left cell as 0.
  • Define the eight possible moves of a knight using dx and dy arrays.
  • At each step, try all eight possible knight moves from the current cell.
  • If a move is within bounds and visits an unvisited cell, mark it with the current step number.
  • Recursively continue from the new cell. If the path fails, backtrack by resetting the cell to -1.
  • If all n² cells are visited, return the board; if no valid tour exists, return an empty array.
C++
#include <iostream>
#include <vector>
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<int>> &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<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;
}

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

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

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

    return {};
}

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.*;

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;
        }

        return new ArrayList<>();
    }

    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
# Utility function to check if the
# move is valid
def isSafe(x, y, n, board):
    return (x >= 0 and y >= 0 and x < n and y < n
            and board[x][y] == -1)

# Recursive function to solve Knight's Tour
def knightTourUtil(x, y, step, n, board, dx, dy):
    
    # 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, dx, dy):
                return True

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

    return False

# Function to start Knight's Tour
def knightTour(n):
    
    # 8 directions of knight moves
    dx = [2, 1, -1, -2, -2, -1, 1, 2]
    dy = [1, 2, 2, 1, -1, -2, -2, -1]

    board = [[-1] * n for _ in range(n)]

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

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

    return []


# Driver Code
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 {
    
    // 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 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);
    }

    // Recursive function to solve Knight's Tour
    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;
    }

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

        for (int i = 0; i < n; i++) {
            List<int> 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> >();
    }

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

        foreach(List<int> row in res)
        {
            foreach(int val in row)
            {
                Console.Write(val + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
// Utility function to check if the
// move is valid
function isSafe(x, y, n, board)
{
    return (x >= 0 && y >= 0 && x < n && y < n
            && board[x][y] === -1);
}

// Recursive function to solve Knight's Tour
function knightTourUtil(x, y, step, n, board, dx, dy)
{
    // If all squares are visited
    if (step === n * n) {
        return true;
    }

    // Try all 8 possible knight moves
    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,
                               dx, dy)) {
                return true;
            }

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

    return false;
}

// Function to start Knight's Tour
function knightTour(n)
{
    // 8 directions of knight moves
    const dx = [ 2, 1, -1, -2, -2, -1, 1, 2 ];
    const dy = [ 1, 2, 2, 1, -1, -2, -2, -1 ];

    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, dx, dy)) {
        return board;
    }

    return [];
}

// 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 

Warnsdorff's Algorithm - O(8^(n * n)) Time and O(n^2) Space

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.

Warnsdorff’s Algorithm 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).

Illustration:

ezg3
  • Initialize an n × n board with -1 and mark the top-left cell as 0.
  • From the current cell, find all valid moves to unvisited cells.
  • For each valid move, count the number of unvisited cells the knight can move to next.
  • Sort the valid moves in ascending order of their onward-move counts.
  • Try the moves in sorted order, recursively continuing the tour and backtracking if a move leads to failure.
  • If all n*n cells are visited, return the completed board; otherwise, return an empty array if no tour is found.
C++
#include <algorithm>
#include <iostream>
#include <vector>
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<int>> &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<int>> getSortedMoves(vector<vector<int>> &board, int x, int y)
{
    vector<vector<int>> 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<int>> &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<int>> knightTour(int n)
{
    vector<vector<int>> board(n, vector<int>(n, -1));

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

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

    return {};
}

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

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

    return 0;
}
Java
import java.util.*;

class GFG {

    // Count the number of onward moves from position (x, y)
    static int
    countOptions(ArrayList<ArrayList<Integer> > board,
                 int x, int y, int[][] dir)
    {
        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.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, int[][] dir)
    {
        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, dir);
                moveList.add(new ArrayList<>(
                    Arrays.asList(options, i)));
            }
        }

        // Sort using lexicographic comparison
        moveList.sort((a, b) -> {
            if (!a.get(0).equals(b.get(0))) {
                return Integer.compare(a.get(0), b.get(0));
            }
            return Integer.compare(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,
                   int[][] dir)
    {
        if (step == n * n)
            return true;

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

        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,
                               dir))
                return true;

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

    // Function to start Knight's Tour
    static ArrayList<ArrayList<Integer> > knightTour(int n)
    {
        // Define 8 knight moves
        int[][] dir = { { 2, 1 },  { 1, 2 },   { -1, 2 },
                        { -2, 1 }, { -2, -1 }, { -1, -2 },
                        { 1, -2 }, { 2, -1 } };

        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, dir)) {
            return board;
        }

        return new ArrayList<>();
    }

    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
# Count the number of onward moves from position (x, y)
def countOptions(board, x, y, dir):
    count = 0
    n = len(board)

    for i in range(8):
        nx = x + dir[i][0]
        ny = y + dir[i][1]

        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, dir):
    moveList = []
    n = len(board)

    for i in range(8):
        nx = x + dir[i][0]
        ny = y + dir[i][1]

        if (0 <= nx < n and 0 <= ny < n
                and board[nx][ny] == -1):
            options = countOptions(board, nx, ny, dir)
            moveList.append([options, i])

    # Sort using default list lexicographic comparison
    moveList.sort()

    return moveList


# Recursive function to solve the Knight's Tour
def knightTourUtil(x, y, step, n, board, dir):
    if step == n * n:
        return True

    moves = getSortedMoves(board, x, y, dir)

    for move in moves:
        dirIdx = move[1]
        nx = x + dir[dirIdx][0]
        ny = y + dir[dirIdx][1]

        board[nx][ny] = step

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

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

    return False


# Function to start Knight's Tour
def knightTour(n):
    
    # Define 8 knight moves
    dir = [
        [2, 1], [1, 2], [-1, 2], [-2, 1],
        [-2, -1], [-1, -2], [1, -2], [2, -1]
    ]

    board = [[-1] * n for _ in range(n)]

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

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

    return []


# Driver Code
if __name__ == "__main__":
    n = 5
    result = knightTour(n)

    for row in result:
        for val in row:
            print(val, end=" ")
        print()
C#
using System;
using System.Collections.Generic;

class GFG {
    
    // Count the number of onward moves from position (x, y)
    static int countOptions(List<List<int> > board, int x,
                            int y, int[, ] dir)
    {
        int count = 0;
        int n = board.Count;

        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<List<int> >
    getSortedMoves(List<List<int> > board, int x, int y,
                   int[, ] dir)
    {
        List<List<int> > moveList = new List<List<int> >();
        int n = board.Count;

        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, dir);
                moveList.Add(new List<int>{ options, i });
            }
        }

        // Sort using lexicographic comparison
        moveList.Sort((a, b) => {
            int cmp = a[0].CompareTo(b[0]);
            if (cmp != 0)
                return cmp;

            return 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,
                               List<List<int> > board,
                               int[, ] dir)
    {
        if (step == n * n)
            return true;

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

        foreach(List<int> 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,
                               dir))
                return true;

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

        return false;
    }

    // Function to start Knight's Tour
    static List<List<int> > knightTour(int n)
    {
        // Define 8 knight moves
        int[, ] dir = { { 2, 1 },  { 1, 2 },   { -1, 2 },
                        { -2, 1 }, { -2, -1 }, { -1, -2 },
                        { 1, -2 }, { 2, -1 } };

        List<List<int> > board = new List<List<int> >();

        for (int i = 0; i < n; i++) {
            List<int> 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, dir))
            return board;

        return new List<List<int> >();
    }

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

        foreach(List<int> row in result)
        {
            foreach(int val in row)
                Console.Write(val + " ");

            Console.WriteLine();
        }
    }
}
JavaScript
// Count the number of onward moves from position (x, y)
function countOptions(board, x, y, dir)
{
    let count = 0;
    const n = board.length;

    for (let i = 0; i < 8; i++) {
        const nx = x + dir[i][0];
        const 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, dir)
{
    const moveList = [];
    const n = board.length;

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

        if (nx >= 0 && ny >= 0 && nx < n && ny < n
            && board[nx][ny] === -1) {
            const options
                = countOptions(board, nx, ny, dir);
            moveList.push([ options, i ]);
        }
    }

    // Sort using lexicographic comparison
    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, dir)
{
    if (step === n * n)
        return true;

    const moves = getSortedMoves(board, x, y, dir);

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

        board[nx][ny] = step;

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

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

    return false;
}

// Function to start Knight's Tour
function knightTour(n)
{
    // Define 8 knight moves
    const dir = [
        [ 2, 1 ], [ 1, 2 ], [ -1, 2 ], [ -2, 1 ],
        [ -2, -1 ], [ -1, -2 ], [ 1, -2 ], [ 2, -1 ]
    ];

    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, dir))
        return board;

    return [];
}

// Driver Code
const n = 5;
const result = knightTour(n);

for (const 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 
Comment