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 [].
Table of Content
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.
#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;
}
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();
}
}
}
# 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()
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();
}
}
}
// 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:

- 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.
#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;
}
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();
}
}
}
# 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()
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();
}
}
}
// 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