Sudoku using Cross-Hatching with backtracking

This method is an optimization of the above method 2. It runs 5X times faster than method 2. Like we used to fill sudoku by first identifying the element which is almost filled. It starts with identifying the row and column where the element should be placed. Picking the almost-filled elements first will give better pruning.

Follow the steps below to solve the problem:

  1. Build a graph with pending elements mapped to row and column coordinates where they can be fitted in the original matrix.
  2. Pick the elements from the graph sorted by fewer remaining elements to be filled.
  3. Recursively fill the elements using a graph into the matrix. Backtrack once an unsafe position is discovered.

Below is the implementation of the above approach:

C++




// C++ Code
#include <algorithm>
#include <bits/stdc++.h>
#include <map>
#include <vector>
 
using namespace std;
 
// Input matrix
vector<vector<int> > arr
    = { { 3, 0, 6, 5, 0, 8, 4, 0, 0 },
        { 5, 2, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 8, 7, 0, 0, 0, 0, 3, 1 },
        { 0, 0, 3, 0, 1, 0, 0, 8, 0 },
        { 9, 0, 0, 8, 6, 3, 0, 0, 5 },
        { 0, 5, 0, 0, 9, 0, 6, 0, 0 },
        { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 7, 4 },
        { 0, 0, 5, 2, 0, 6, 3, 0, 0 } };
 
// Position of the input elements in the arr
// pos = {
//     element: [[position 1], [position 2]]
// }
map<int, vector<vector<int> > > pos;
 
// Count of the remaining number of the elements
// rem = {
//     element: pending count
// }
map<int, int> rem;
 
// Graph defining tentative positions of the elements to be
// filled graph = {
//     key: {
//         row1: [columns],
//         row2: [columns]
//     }
// }
map<int, map<int, vector<int> > > graph;
 
// Print the matrix array
void printMatrix()
{
  for (int i = 0; i < 9; i++) {
    for (int j = 0; j < 9; j++) {
      cout << arr[i][j] << " ";
    }
    cout << endl;
  }
}
 
// Method to check if the inserted element is safe
bool is_safe(int x, int y)
{
  int key = arr[x][y];
  for (int i = 0; i < 9; i++) {
    if (i != y && arr[x][i] == key) {
      return false;
    }
    if (i != x && arr[i][y] == key) {
      return false;
    }
  }
 
  int r_start = floor(x / 3) * 3;
  int r_end = r_start + 3;
 
  int c_start = floor(y / 3) * 3;
  int c_end = c_start + 3;
 
  for (int i = r_start; i < r_end; i++) {
    for (int j = c_start; j < c_end; j++) {
      if (i != x && j != y && arr[i][j] == key) {
        return false;
      }
    }
  }
  return true;
}
 
// method to fill the matrix
// input keys: list of elements to be filled in the matrix
//        k   : index number of the element to be picked up
//        from keys rows: list of row index where element is
//        to be inserted r   : index number of the row to be
//        inserted
//
bool fill_matrix(int k, vector<int> keys, int r,
                 vector<int> rows)
{
  int c = 0;
  arr[rows[r]] = keys[k];
  if (is_safe(rows[r], c)) {
    if (r < rows.size() - 1) {
      if (fill_matrix(k, keys, r + 1, rows)) {
        return true;
      }
      else {
        arr[rows[r]] = 0;
      }
    }
    else {
      if (k < keys.size() - 1) {
        if (fill_matrix(
          k + 1, keys, 0,
          rows)) {
          return true;
        }
        else {
          arr[rows[r]] = 0;
 
        }
      }
      return true;
    }
  }
  arr[rows[r]] = 0;
 
  return false;
}
 
// Fill the pos and rem dictionary. It will be used to build
// graph
void build_pos_and_rem()
{
  for (int i = 0; i < 9; i++) {
    for (int j = 0; j < 9; j++) {
      if (arr[i][j] > 0) {
        if (!pos.count(arr[i][j])) {
          pos[arr[i][j]] = {};
        }
        pos[arr[i][j]].push_back({ i, j });
        if (!rem.count(arr[i][j])) {
          rem[arr[i][j]] = 9;
        }
        rem[arr[i][j]] -= 1;
      }
    }
  }
 
  // Fill the elements not present in input matrix.
  // Example: 1 is missing in input matrix
  for (int i = 1; i < 10; i++) {
    if (!pos.count(i)) {
      pos[i] = {};
    }
    if (!rem.count(i)) {
      rem[i] = 9;
    }
  }
}
 
int main() { printMatrix(); }
 
// This code is contributed by ishankhandelwals.


Python3




# This program works by identifying the remaining elements and backtrack only on those.
# The elements are inserted in the increasing order of the elements left to be inserted. And hence runs much faster.
# Comparing with other back tracking algorithms, it runs 5X faster.
 
# Input matrix
arr = [
    [3, 0, 6, 5, 0, 8, 4, 0, 0],
    [5, 2, 0, 0, 0, 0, 0, 0, 0],
    [0, 8, 7, 0, 0, 0, 0, 3, 1],
    [0, 0, 3, 0, 1, 0, 0, 8, 0],
    [9, 0, 0, 8, 6, 3, 0, 0, 5],
    [0, 5, 0, 0, 9, 0, 6, 0, 0],
    [1, 3, 0, 0, 0, 0, 2, 5, 0],
    [0, 0, 0, 0, 0, 0, 0, 7, 4],
    [0, 0, 5, 2, 0, 6, 3, 0, 0]
]
 
# Position of the input elements in the arr
# pos = {
#     element: [[position 1], [position 2]]
# }
pos = {}
 
# Count of the remaining number of the elements
# rem = {
#     element: pending count
# }
rem = {}
 
# Graph defining tentative positions of the elements to be filled
# graph = {
#     key: {
#         row1: [columns],
#         row2: [columns]
#     }
# }
graph = {}
 
 
# Print the matrix array
def printMatrix():
    for i in range(0, 9):
        for j in range(0, 9):
            print(str(arr[i][j]), end=" ")
        print()
 
 
# Method to check if the inserted element is safe
def is_safe(x, y):
    key = arr[x][y]
    for i in range(0, 9):
        if i != y and arr[x][i] == key:
            return False
        if i != x and arr[i][y] == key:
            return False
 
    r_start = int(x / 3) * 3
    r_end = r_start + 3
 
    c_start = int(y / 3) * 3
    c_end = c_start + 3
 
    for i in range(r_start, r_end):
        for j in range(c_start, c_end):
            if i != x and j != y and arr[i][j] == key:
                return False
    return True
 
 
# method to fill the matrix
# input keys: list of elements to be filled in the matrix
#        k   : index number of the element to be picked up from keys
#        rows: list of row index where element is to be inserted
#        r   : index number of the row to be inserted
#
def fill_matrix(k, keys, r, rows):
    for c in graph[keys[k]][rows[r]]:
        if arr[rows[r]] > 0:
            continue
        arr[rows[r]] = keys[k]
        if is_safe(rows[r], c):
            if r < len(rows) - 1:
                if fill_matrix(k, keys, r + 1, rows):
                    return True
                else:
                    arr[rows[r]] = 0
                    continue
            else:
                if k < len(keys) - 1:
                    if fill_matrix(k + 1, keys, 0, list(graph[keys[k + 1]].keys())):
                        return True
                    else:
                        arr[rows[r]] = 0
                        continue
                return True
        arr[rows[r]] = 0
    return False
 
 
# Fill the pos and rem dictionary. It will be used to build graph
def build_pos_and_rem():
    for i in range(0, 9):
        for j in range(0, 9):
            if arr[i][j] > 0:
                if arr[i][j] not in pos:
                    pos[arr[i][j]] = []
                pos[arr[i][j]].append([i, j])
                if arr[i][j] not in rem:
                    rem[arr[i][j]] = 9
                rem[arr[i][j]] -= 1
 
    # Fill the elements not present in input matrix. Example: 1 is missing in input matrix
    for i in range(1, 10):
        if i not in pos:
            pos[i] = []
        if i not in rem:
            rem[i] = 9
 
# Build the graph
 
 
def build_graph():
    for k, v in pos.items():
        if k not in graph:
            graph[k] = {}
 
        row = list(range(0, 9))
        col = list(range(0, 9))
 
        for cord in v:
            row.remove(cord[0])
            col.remove(cord[1])
 
        if len(row) == 0 or len(col) == 0:
            continue
 
        for r in row:
            for c in col:
                if arr[r] == 0:
                    if r not in graph[k]:
                        graph[k][r] = []
                    graph[k][r].append(c)
 
 
build_pos_and_rem()
 
# Sort the rem map in order to start with smaller number of elements to be filled first. Optimization for pruning
rem = {k: v for k, v in sorted(rem.items(), key=lambda item: item[1])}
 
build_graph()
 
key_s = list(rem.keys())
# Util called to fill the matrix
fill_matrix(0, key_s, 0, list(graph[key_s[0]].keys()))
 
printMatrix()
 
# This code is contributed by Arun Kumar


Javascript




// convert below python code to js code
// # This program works by identifying the remaining elements and backtrack only on those.
// # The elements are inserted in the increasing order of the elements left to be inserted. And hence runs much faster.
// # Comparing with other back tracking algorithms, it runs 5X faster.
 
// # Input matrix
// arr = [
//     [3, 0, 6, 5, 0, 8, 4, 0, 0],
//     [5, 2, 0, 0, 0, 0, 0, 0, 0],
//     [0, 8, 7, 0, 0, 0, 0, 3, 1],
//     [0, 0, 3, 0, 1, 0, 0, 8, 0],
//     [9, 0, 0, 8, 6, 3, 0, 0, 5],
//     [0, 5, 0, 0, 9, 0, 6, 0, 0],
//     [1, 3, 0, 0, 0, 0, 2, 5, 0],
//     [0, 0, 0, 0, 0, 0, 0, 7, 4],
//     [0, 0, 5, 2, 0, 6, 3, 0, 0]
// ]
 
// # Position of the input elements in the arr
// # pos = {
// #     element: [[position 1], [position 2]]
// # }
// pos = {}
 
// # Count of the remaining number of the elements
// # rem = {
// #     element: pending count
// # }
// rem = {}
 
// # Graph defining tentative positions of the elements to be filled
// # graph = {
// #     key: {
// #         row1: [columns],
// #         row2: [columns]
// #     }
// # }
// graph = {}
 
 
// # Print the matrix array
// def printMatrix():
//     for i in range(0, 9):
//         for j in range(0, 9):
//             print(str(arr[i][j]), end=" ")
//         print()
 
 
// # Method to check if the inserted element is safe
// def is_safe(x, y):
//     key = arr[x][y]
//     for i in range(0, 9):
//         if i != y and arr[x][i] == key:
//             return False
//         if i != x and arr[i][y] == key:
//             return False
 
//     r_start = int(x / 3) * 3
//     r_end = r_start + 3
 
//     c_start = int(y / 3) * 3
//     c_end = c_start + 3
 
//     for i in range(r_start, r_end):
//         for j in range(c_start, c_end):
//             if i != x and j != y and arr[i][j] == key:
//                 return False
//     return True
 
 
// # method to fill the matrix
// # input keys: list of elements to be filled in the matrix
// #        k   : index number of the element to be picked up from keys
// #        rows: list of row index where element is to be inserted
// #        r   : index number of the row to be inserted
// #
// def fill_matrix(k, keys, r, rows):
//     for c in graph[keys[k]][rows[r]]:
//         if arr[rows[r]] > 0:
//             continue
//         arr[rows[r]] = keys[k]
//         if is_safe(rows[r], c):
//             if r < len(rows) - 1:
//                 if fill_matrix(k, keys, r + 1, rows):
//                     return True
//                 else:
//                     arr[rows[r]] = 0
//                     continue
//             else:
//                 if k < len(keys) - 1:
//                     if fill_matrix(k + 1, keys, 0, list(graph[keys[k + 1]].keys())):
//                         return True
//                     else:
//                         arr[rows[r]] = 0
//                         continue
//                 return True
//         arr[rows[r]] = 0
//     return False
 
 
// # Fill the pos and rem dictionary. It will be used to build graph
// def build_pos_and_rem():
//     for i in range(0, 9):
//         for j in range(0, 9):
//             if arr[i][j] > 0:
//                 if arr[i][j] not in pos:
//                     pos[arr[i][j]] = []
//                 pos[arr[i][j]].append([i, j])
//                 if arr[i][j] not in rem:
//                     rem[arr[i][j]] = 9
//                 rem[arr[i][j]] -= 1
 
//     # Fill the elements not present in input matrix. Example: 1 is missing in input matrix
//     for i in range(1, 10):
//         if i not in pos:
//             pos[i] = []
//         if i not in rem:
//             rem[i] = 9
 
// # Build the graph
 
 
// def build_graph():
//     for k, v in pos.items():
//         if k not in graph:
//             graph[k] = {}
 
//         row = list(range(0, 9))
//         col = list(range(0, 9))
 
//         for cord in v:
//             row.remove(cord[0])
//             col.remove(cord[1])
 
//         if len(row) == 0 or len(col) == 0:
//             continue
 
//         for r in row:
//             for c in col:
//                 if arr[r] == 0:
//                     if r not in graph[k]:
//                         graph[k][r] = []
//                     graph[k][r].append(c)
 
 
// build_pos_and_rem()
 
// # Sort the rem map in order to start with smaller number of elements to be filled first. Optimization for pruning
// rem = {k: v for k, v in sorted(rem.items(), key=lambda item: item[1])}
 
// build_graph()
 
// key_s = list(rem.keys())
// # Util called to fill the matrix
// fill_matrix(0, key_s, 0, list(graph[key_s[0]].keys()))
 
// printMatrix()
 
// # This code is contributed by Arun Kumar
 
// JavaScript Code
 
// Input matrix
let arr = [
    [3, 0, 6, 5, 0, 8, 4, 0, 0],
    [5, 2, 0, 0, 0, 0, 0, 0, 0],
    [0, 8, 7, 0, 0, 0, 0, 3, 1],
    [0, 0, 3, 0, 1, 0, 0, 8, 0],
    [9, 0, 0, 8, 6, 3, 0, 0, 5],
    [0, 5, 0, 0, 9, 0, 6, 0, 0],
    [1, 3, 0, 0, 0, 0, 2, 5, 0],
    [0, 0, 0, 0, 0, 0, 0, 7, 4],
    [0, 0, 5, 2, 0, 6, 3, 0, 0]
]
 
// Position of the input elements in the arr
// pos = {
//     element: [[position 1], [position 2]]
// }
let pos = {};
 
// Count of the remaining number of the elements
// rem = {
//     element: pending count
// }
let rem = {};
 
// Graph defining tentative positions of the elements to be filled
// graph = {
//     key: {
//         row1: [columns],
//         row2: [columns]
//     }
// }
let graph = {};
 
 
// Print the matrix array
function printMatrix() {
    for (let i = 0; i < 9; i++) {
        for (let j = 0; j < 9; j++) {
            process.stdout.write(arr[i][j]+" ");
        }
        console.log();
    }
}
 
 
// Method to check if the inserted element is safe
function is_safe(x, y) {
    let key = arr[x][y];
    for (let i = 0; i < 9; i++) {
        if (i !== y && arr[x][i] === key) {
            return false;
        }
        if (i !== x && arr[i][y] === key) {
            return false;
        }
    }
 
    let r_start = Math.floor(x / 3) * 3;
    let r_end = r_start + 3;
 
    let c_start = Math.floor(y / 3) * 3;
    let c_end = c_start + 3;
 
    for (let i = r_start; i < r_end; i++) {
        for (let j = c_start; j < c_end; j++) {
            if (i !== x && j !== y && arr[i][j] === key) {
                return false;
            }
        }
    }
    return true;
}
 
 
// method to fill the matrix
// input keys: list of elements to be filled in the matrix
//        k   : index number of the element to be picked up from keys
//        rows: list of row index where element is to be inserted
//        r   : index number of the row to be inserted
//
function fill_matrix(k, keys, r, rows) {
    for (let c of graph[keys[k]][rows[r]]) {
        if (arr[rows[r]] > 0) {
            continue;
        }
        arr[rows[r]] = keys[k];
        if (is_safe(rows[r], c)) {
            if (r < rows.length - 1) {
                if (fill_matrix(k, keys, r + 1, rows)) {
                    return true;
                } else {
                    arr[rows[r]] = 0;
                    continue;
                }
            } else {
                if (k < keys.length - 1) {
                    if (fill_matrix(k + 1, keys, 0, list(graph[keys[k + 1]].keys()))) {
                        return true;
                    } else {
                        arr[rows[r]] = 0;
                        continue;
                    }
                }
                return true;
            }
        }
        arr[rows[r]] = 0;
    }
    return false;
}
 
 
// Fill the pos and rem dictionary. It will be used to build graph
function build_pos_and_rem() {
    for (let i = 0; i < 9; i++) {
        for (let j = 0; j < 9; j++) {
            if (arr[i][j] > 0) {
                if (!pos.hasOwnProperty(arr[i][j])) {
                    pos[arr[i][j]] = [];
                }
                pos[arr[i][j]].push([i, j]);
                if (!rem.hasOwnProperty(arr[i][j])) {
                    rem[arr[i][j]] = 9;
                }
                rem[arr[i][j]] -= 1;
            }
        }
    }
 
    // Fill the elements not present in input matrix. Example: 1 is missing in input matrix
    for (let i = 1; i < 10; i++) {
        if (!pos.hasOwnProperty(i)) {
            pos[i] = [];
        }
        if (!rem.hasOwnProperty(i)) {
            rem[i] = 9;
        }
    }
}
 
// Build the graph
function build_graph() {
    for (let [k, v] of Object.entries(pos)) {
        if (!graph.hasOwnProperty(k)) {
            graph[k] = {};
        }
 
        let row = [...Array(9).keys()];
        let col = [...Array(9).keys()];
 
        for (let cord of v) {
            row.splice(row.indexOf(cord[0]), 1);
            col.splice(col.indexOf(cord[1]), 1);
        }
 
        if (row.length === 0 || col.length === 0) {
            continue;
        }
 
        for (let r of row) {
            for (let c of col) {
                if (arr[r] === 0) {
                    if (!graph[k].hasOwnProperty(r)) {
                        graph[k][r] = [];
                    }
                    graph[k][r].push(c);
                }
            }
        }
    }
}
 
build_pos_and_rem();
 
// Sort the rem map in order to start with smaller number of elements to be filled first. Optimization for pruning
rem = Object.fromEntries(Object.entries(rem).sort((a, b) => a[1] - b[1]));
 
build_graph();
 
let key_s = Object.keys(rem);
// Util called to fill the matrix
fill_matrix(0, key_s, 0, Object.keys(graph[key_s[0]]));
 
printMatrix();


Java




// Java code
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
 
 class Element {
        int row, col;
        List<Integer> candidates;
 
        Element(int row, int col) {
            this.row = row;
            this.col = col;
            this.candidates = new ArrayList<>();
        }
    }
 
// Input matrix
class Main {
    static final int N = 9;
    static int[][] grid = {
            {3, 0, 6, 5, 0, 8, 4, 0, 0},
            {5, 2, 0, 0, 0, 0, 0, 0, 0},
            {0, 8, 7, 0, 0, 0, 0, 3, 1},
            {0, 0, 3, 0, 1, 0, 0, 8, 0},
            {9, 0, 0, 8, 6, 3, 0, 0, 5},
            {0, 5, 0, 0, 9, 0, 6, 0, 0},
            {1, 3, 0, 0, 0, 0, 2, 5, 0},
            {0, 0, 0, 0, 0, 0, 0, 7, 4},
            {0, 0, 5, 2, 0, 6, 3, 0, 0}
    };
 
    static List<Element> graph;
 
   
// Method to check if the inserted element is safe
    static boolean isSafe(int row, int col, int num) {
        // check row
        for (int i = 0; i < N; i++) {
            if (grid[row][i] == num) {
                return false;
            }
        }
 
        // check column
        for (int i = 0; i < N; i++) {
            if (grid[i][col] == num) {
                return false;
            }
        }
 
        // check subgrid
        int subgridRow = row - row % 3;
        int subgridCol = col - col % 3;
        for (int i = subgridRow; i < subgridRow + 3; i++) {
            for (int j = subgridCol; j < subgridCol + 3; j++) {
                if (grid[i][j] == num) {
                    return false;
                }
            }
        }
 
        return true;
    }
   
//initialize the graph
    static void initializeGraph() {
        graph = new ArrayList<>();
        for (int row = 0; row < N; ++row) {
            for (int col = 0; col < N; ++col) {
                if (grid[row][col] == 0) {
                    Element e = new Element(row, col);
                    for (int num = 1; num <= N; ++num) {
                        if (isSafe(row, col, num)) {
                            e.candidates.add(num);
                        }
                    }
                    graph.add(e);
                }
            }
        }
    }
 
   
// Sort the rem map in order to start with smaller number of elements
  //to be filled first.
    static int sortByFewestCandidates(Element a, Element b) {
         return a.candidates.size() - b.candidates.size();
    }
 
    static boolean solveSudoku() {
        if (graph.isEmpty()) {
            return true;
        }
 
        Collections.sort(graph, Main::sortByFewestCandidates);
        Element e = graph.get(graph.size() - 1);
        graph.remove(graph.size() -1);
       //  graph.pop_back();
    int row = e.row;
    int col = e.col;
         
    for (int i = 0; i < e.candidates.size(); ++i) {
        int num = e.candidates.get(i);
        if (isSafe(e.row, e.col, num)) {
            grid[e.row][e.col] = num;
            graph.remove(e);
            if (solveSudoku()) {
                return true;
            }
            graph.add(e);
            Collections.sort(graph, Main::sortByFewestCandidates);
            grid[e.row][e.col] = 0;
        }
    }
    return false;
}
 
public static void main(String[] args) {
    initializeGraph();
    solveSudoku();
 
    // print solved sudoku
    for (int[] row : grid) {
        for (int num : row) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}
}


C#




// C# Code
using System;
using System.Collections.Generic;
 
namespace sudoku
{
    class Program
    {
        // Input matrix
        static int[,] arr = new int[9, 9] {
            { 3, 0, 6, 5, 0, 8, 4, 0, 0 },
            { 5, 2, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 8, 7, 0, 0, 0, 0, 3, 1 },
            { 0, 0, 3, 0, 1, 0, 0, 8, 0 },
            { 9, 0, 0, 8, 6, 3, 0, 0, 5 },
            { 0, 5, 0, 0, 9, 0, 6, 0, 0 },
            { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 7, 4 },
            { 0, 0, 5, 2, 0, 6, 3, 0, 0 }
        };
 
        // Position of the input elements in the arr
        // pos = {
        //     element: [[position 1], [position 2]]
        // }
        static Dictionary<int, List<int[]>> pos = new Dictionary<int, List<int[]>>();
 
        // Count of the remaining number of the elements
        // rem = {
        //     element: pending count
        // }
        static Dictionary<int, int> rem = new Dictionary<int, int>();
 
        // Graph defining tentative positions of the elements to be
        // filled graph = {
        //     key: {
        //         row1: [columns],
        //         row2: [columns]
        //     }
        // }
        static Dictionary<int, Dictionary<int, List<int>>> graph = new Dictionary<int, Dictionary<int, List<int>>>();
 
        // Print the matrix array
        static void PrintMatrix()
        {
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    Console.Write(arr[i, j] + " ");
                }
                Console.WriteLine();
            }
        }
 
        // Method to check if the inserted element is safe
        static bool IsSafe(int x, int y)
        {
            int key = arr[x, y];
            for (int i = 0; i < 9; i++)
            {
                if (i != y && arr[x, i] == key)
                {
                    return false;
                }
                if (i != x && arr[i, y] == key)
                {
                    return false;
                }
            }
 
            int r_start = (int)Math.Floor((double)x / 3) * 3;
            int r_end = r_start + 3;
 
            int c_start = (int)Math.Floor((double)y / 3) * 3;
            int c_end = c_start + 3;
 
            for (int i = r_start; i < r_end; i++)
            {
                for (int j = c_start; j < c_end; j++)
                {
                    if (i != x && j != y && arr[i, j] == key)
                    {
                        return false;
                    }
                }
            }
            return true;
        }
 
        // method to fill the matrix
        // input keys: list of elements to be filled in the matrix
        //        k   : index number of the element to be picked up
        //        from keys rows: list of row index where element is
        //        to be inserted r   : index number of the row to be
        //        inserted
        //
        static bool FillMatrix(int k, List<int> keys, int r, List<int> rows)
        {
            int c = 0;
            arr[rows[r], c] = keys[k];
            if (IsSafe(rows[r], c))
            {
                if (r < rows.Count - 1)
                {
                    if (FillMatrix(k, keys, r + 1, rows))
                    {
                        return true;
                    }
                    else
                    {
                        arr[rows[r], c] = 0;
                    }
                }
                else
                {
                    if (k < keys.Count - 1)
                    {
                        if (FillMatrix(
                            k + 1, keys, 0,
                            rows))
                        {
                            return true;
                        }
                        else
                        {
                            arr[rows[r], c] = 0;
 
                        }
                    }
                    return true;
                }
            }
            arr[rows[r], c] = 0;
 
            return false;
        }
 
        // Fill the pos and rem dictionary. It will be used to build
        // graph
        static void BuildPosAndRem()
        {
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    if (arr[i, j] > 0)
                    {
                        if (!pos.ContainsKey(arr[i, j]))
                        {
                            pos[arr[i, j]] = new List<int[]>();
                        }
                        pos[arr[i, j]].Add(new int[] { i, j });
                        if (!rem.ContainsKey(arr[i, j]))
                        {
                            rem[arr[i, j]] = 9;
                        }
                        rem[arr[i, j]] -= 1;
                    }
                }
            }
 
            // Fill the elements not present in input matrix.
            // Example: 1 is missing in input matrix
            for (int i = 1; i < 10; i++)
            {
                if (!pos.ContainsKey(i))
                {
                    pos[i] = new List<int[]>();
                }
                if (!rem.ContainsKey(i))
                {
                    rem[i] = 9;
                }
            }
        }
 
        static void Main(string[] args)
        {
            PrintMatrix();
        }
    }
}


Output

3 1 6 5 7 8 4 9 2 
5 2 9 1 3 4 7 6 8 
4 8 7 6 2 9 5 3 1 
2 6 3 4 1 5 9 8 7 
9 7 4 8 6 3 1 2 5 
8 5 1 7 9 2 6 4 3 
1 3 8 9 4 7 2 5 6 
6 9 2 3 5 1 8 7 4 
7 4 5 2 8 6 3 1 9 

Time complexity: O(9^(n*n)).  Due to the element that needs to fit in a cell will come earlier as we are filling almost filled elements first, it will help in less number of recursive calls. So the time taken will be much less than the naive approaches but the upper bound time complexity remains the same.
Auxiliary Space: O(n*n).  A graph of the remaining positions to be filled for the respected elements is created.



Algorithm to Solve Sudoku | Sudoku Solver

Given a partially filled 9×9 2D array ‘grid[9][9]’, the goal is to assign digits (from 1 to 9) to the empty cells so that every row, column, and subgrid of size 3×3 contains exactly one instance of the digits from 1 to 9. 

Examples: 

Input: grid
{ {3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0}, 
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0} }
Output:
3 1 6 5 7 8 4 9 2
5 2 9 1 3 4 7 6 8
4 8 7 6 2 9 5 3 1
2 6 3 4 1 5 9 8 7
9 7 4 8 6 3 1 2 5
8 5 1 7 9 2 6 4 3
1 3 8 9 4 7 2 5 6
6 9 2 3 5 1 8 7 4
7 4 5 2 8 6 3 1 9
Explanation: Each row, column and 3*3 box of the output matrix contains unique numbers.

Input: grid
{ { 3, 1, 6, 5, 7, 8, 4, 9, 2 },
{ 5, 2, 9, 1, 3, 4, 7, 6, 8 },
{ 4, 8, 7, 6, 2, 9, 5, 3, 1 },
{ 2, 6, 3, 0, 1, 5, 9, 8, 7 },
{ 9, 7, 4, 8, 6, 0, 1, 2, 5 },
{ 8, 5, 1, 7, 9, 2, 6, 4, 3 },
{ 1, 3, 8, 0, 4, 7, 2, 0, 6 },
{ 6, 9, 2, 3, 5, 1, 8, 7, 4 },
{ 7, 4, 5, 0, 8, 6, 3, 1, 0 } };
Output:
3 1 6 5 7 8 4 9 2 
5 2 9 1 3 4 7 6 8 
4 8 7 6 2 9 5 3 1 
2 6 3 4 1 5 9 8 7
9 7 4 8 6 3 1 2 5
8 5 1 7 9 2 6 4 3
1 3 8 9 4 7 2 5 6
6 9 2 3 5 1 8 7 4
7 4 5 2 8 6 3 1 9 
Explanation: Each row, column and 3*3 box of the output matrix contains unique numbers.

Recommended Practice

Naive Approach:

The naive approach is to generate all possible configurations of numbers from 1 to 9 to fill the empty cells. Try every configuration one by one until the correct configuration is found, i.e. for every unassigned position fill the position with a number from 1 to 9. After filling all the unassigned positions check if the matrix is safe or not. If safe print else recurs for other cases.

Follow the steps below to solve the problem:

  • Create a function that checks if the given matrix is valid sudoku or not. Keep Hashmap for the row, column and boxes. If any number has a frequency greater than 1 in the hashMap return false else return true;
  • Create a recursive function that takes a grid and the current row and column index.
  • Check some base cases. 
    • If the index is at the end of the matrix, i.e. i=N-1 and j=N then check if the grid is safe or not, if safe print the grid and return true else return false. 
    • The other base case is when the value of column is N, i.e j = N, then move to next row, i.e. i++ and j = 0.
  • If the current index is not assigned then fill the element from 1 to 9 and recur for all 9 cases with the index of next element, i.e. i, j+1. if the recursive call returns true then break the loop and return true.
  • If the current index is assigned then call the recursive function with the index of the next element, i.e. i, j+1

Below is the implementation of the above approach:

C++




#include <iostream>
 
using namespace std;
 
// N is the size of the 2D matrix   N*N
#define N 9
 
/* A utility function to print grid */
void print(int arr[N][N])
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            cout << arr[i][j] << " ";
        cout << endl;
    }
}
 
// Checks whether it will be
// legal to assign num to the
// given row, col
bool isSafe(int grid[N][N], int row,
                       int col, int num)
{
     
    // Check if we find the same num
    // in the similar row , we
    // return false
    for (int x = 0; x <= 8; x++)
        if (grid[row][x] == num)
            return false;
 
    // Check if we find the same num in
    // the similar column , we
    // return false
    for (int x = 0; x <= 8; x++)
        if (grid[x][col] == num)
            return false;
 
    // Check if we find the same num in
    // the particular 3*3 matrix,
    // we return false
    int startRow = row - row % 3,
            startCol = col - col % 3;
   
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            if (grid[i + startRow][j +
                            startCol] == num)
                return false;
 
    return true;
}
 
/* Takes a partially filled-in grid and attempts
to assign values to all unassigned locations in
such a way to meet the requirements for
Sudoku solution (non-duplication across rows,
columns, and boxes) */
bool solveSudoku(int grid[N][N], int row, int col)
{
    // Check if we have reached the 8th
    // row and 9th column (0
    // indexed matrix) , we are
    // returning true to avoid
    // further backtracking
    if (row == N - 1 && col == N)
        return true;
 
    // Check if column value  becomes 9 ,
    // we move to next row and
    //  column start from 0
    if (col == N) {
        row++;
        col = 0;
    }
   
    // Check if the current position of
    // the grid already contains
    // value >0, we iterate for next column
    if (grid[row][col] > 0)
        return solveSudoku(grid, row, col + 1);
 
    for (int num = 1; num <= N; num++)
    {
         
        // Check if it is safe to place
        // the num (1-9)  in the
        // given row ,col  ->we
        // move to next column
        if (isSafe(grid, row, col, num))
        {
             
           /* Assigning the num in
              the current (row,col)
              position of the grid
              and assuming our assigned
              num in the position
              is correct     */
            grid[row][col] = num;
           
            //  Checking for next possibility with next
            //  column
            if (solveSudoku(grid, row, col + 1))
                return true;
        }
       
        // Removing the assigned num ,
        // since our assumption
        // was wrong , and we go for
        // next assumption with
        // diff num value
        grid[row][col] = 0;
    }
    return false;
}
 
// Driver Code
int main()
{
    // 0 means unassigned cells
    int grid[N][N] = { { 3, 0, 6, 5, 0, 8, 4, 0, 0 },
                       { 5, 2, 0, 0, 0, 0, 0, 0, 0 },
                       { 0, 8, 7, 0, 0, 0, 0, 3, 1 },
                       { 0, 0, 3, 0, 1, 0, 0, 8, 0 },
                       { 9, 0, 0, 8, 6, 3, 0, 0, 5 },
                       { 0, 5, 0, 0, 9, 0, 6, 0, 0 },
                       { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
                       { 0, 0, 0, 0, 0, 0, 0, 7, 4 },
                       { 0, 0, 5, 2, 0, 6, 3, 0, 0 } };
 
    if (solveSudoku(grid, 0, 0))
        print(grid);
    else
        cout << "no solution  exists " << endl;
 
    return 0;
    // This is code is contributed by Pradeep Mondal P
}


C




#include <stdio.h>
#include <stdlib.h>
 
// N is the size of the 2D matrix   N*N
#define N 9
 
/* A utility function to print grid */
void print(int arr[N][N])
{
     for (int i = 0; i < N; i++)
      {
         for (int j = 0; j < N; j++)
            printf("%d ",arr[i][j]);
         printf("\n");
       }
}
 
// Checks whether it will be legal 
// to assign num to the
// given row, col
int isSafe(int grid[N][N], int row,
                       int col, int num)
{
     
    // Check if we find the same num
    // in the similar row , we return 0
    for (int x = 0; x <= 8; x++)
        if (grid[row][x] == num)
            return 0;
 
    // Check if we find the same num in the
    // similar column , we return 0
    for (int x = 0; x <= 8; x++)
        if (grid[x][col] == num)
            return 0;
 
    // Check if we find the same num in the
    // particular 3*3 matrix, we return 0
    int startRow = row - row % 3,
                 startCol = col - col % 3;
   
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            if (grid[i + startRow][j +
                          startCol] == num)
                return 0;
 
    return 1;
}
 
/* Takes a partially filled-in grid and attempts
to assign values to all unassigned locations in
such a way to meet the requirements for
Sudoku solution (non-duplication across rows,
columns, and boxes) */
int solveSudoku(int grid[N][N], int row, int col)
{
     
    // Check if we have reached the 8th row
    // and 9th column (0
    // indexed matrix) , we are
    // returning true to avoid
    // further backtracking
    if (row == N - 1 && col == N)
        return 1;
 
    //  Check if column value  becomes 9 ,
    //  we move to next row and
    //  column start from 0
    if (col == N)
    {
        row++;
        col = 0;
    }
   
    // Check if the current position
    // of the grid already contains
    // value >0, we iterate for next column
    if (grid[row][col] > 0)
        return solveSudoku(grid, row, col + 1);
 
    for (int num = 1; num <= N; num++)
    {
         
        // Check if it is safe to place
        // the num (1-9)  in the
        // given row ,col  ->we move to next column
        if (isSafe(grid, row, col, num)==1)
        {
            /* assigning the num in the
               current (row,col)
               position of the grid
               and assuming our assigned num
               in the position
               is correct     */
            grid[row][col] = num;
           
            //  Checking for next possibility with next
            //  column
            if (solveSudoku(grid, row, col + 1)==1)
                return 1;
        }
       
        // Removing the assigned num ,
        // since our assumption
        // was wrong , and we go for next
        // assumption with
        // diff num value
        grid[row][col] = 0;
    }
    return 0;
}
 
int main()
{
    // 0 means unassigned cells
    int grid[N][N] = { { 3, 0, 6, 5, 0, 8, 4, 0, 0 },
                       { 5, 2, 0, 0, 0, 0, 0, 0, 0 },
                       { 0, 8, 7, 0, 0, 0, 0, 3, 1 },
                       { 0, 0, 3, 0, 1, 0, 0, 8, 0 },
                       { 9, 0, 0, 8, 6, 3, 0, 0, 5 },
                       { 0, 5, 0, 0, 9, 0, 6, 0, 0 },
                       { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
                       { 0, 0, 0, 0, 0, 0, 0, 7, 4 },
                       { 0, 0, 5, 2, 0, 6, 3, 0, 0 } };
 
    if (solveSudoku(grid, 0, 0)==1)
        print(grid);
    else
        printf("No solution exists");
 
    return 0;
    // This is code is contributed by Pradeep Mondal P
}


Java




// Java program for above approach
public class Sudoku {
 
    // N is the size of the 2D matrix   N*N
    static int N = 9;
 
    /* Takes a partially filled-in grid and attempts
    to assign values to all unassigned locations in
    such a way to meet the requirements for
    Sudoku solution (non-duplication across rows,
    columns, and boxes) */
    static boolean solveSudoku(int grid[][], int row,
                               int col)
    {
 
        /*if we have reached the 8th
           row and 9th column (0
           indexed matrix) ,
           we are returning true to avoid further
           backtracking       */
        if (row == N - 1 && col == N)
            return true;
 
        // Check if column value  becomes 9 ,
        // we move to next row
        // and column start from 0
        if (col == N) {
            row++;
            col = 0;
        }
 
        // Check if the current position
        // of the grid already
        // contains value >0, we iterate
        // for next column
        if (grid[row][col] != 0)
            return solveSudoku(grid, row, col + 1);
 
        for (int num = 1; num < 10; num++) {
 
            // Check if it is safe to place
            // the num (1-9)  in the
            // given row ,col ->we move to next column
            if (isSafe(grid, row, col, num)) {
 
                /*  assigning the num in the current
                (row,col)  position of the grid and
                assuming our assigned num in the position
                is correct */
                grid[row][col] = num;
 
                // Checking for next
                // possibility with next column
                if (solveSudoku(grid, row, col + 1))
                    return true;
            }
            /* removing the assigned num , since our
               assumption was wrong , and we go for next
               assumption with diff num value   */
            grid[row][col] = 0;
        }
        return false;
    }
 
    /* A utility function to print grid */
    static void print(int[][] grid)
    {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++)
                System.out.print(grid[i][j] + " ");
            System.out.println();
        }
    }
 
    // Check whether it will be legal
    // to assign num to the
    // given row, col
    static boolean isSafe(int[][] grid, int row, int col,
                          int num)
    {
 
        // Check if we find the same num
        // in the similar row , we
        // return false
        for (int x = 0; x <= 8; x++)
            if (grid[row][x] == num)
                return false;
 
        // Check if we find the same num
        // in the similar column ,
        // we return false
        for (int x = 0; x <= 8; x++)
            if (grid[x][col] == num)
                return false;
 
        // Check if we find the same num
        // in the particular 3*3
        // matrix, we return false
        int startRow = row - row % 3, startCol
                                      = col - col % 3;
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                if (grid[i + startRow][j + startCol] == num)
                    return false;
 
        return true;
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int grid[][] = { { 3, 0, 6, 5, 0, 8, 4, 0, 0 },
                         { 5, 2, 0, 0, 0, 0, 0, 0, 0 },
                         { 0, 8, 7, 0, 0, 0, 0, 3, 1 },
                         { 0, 0, 3, 0, 1, 0, 0, 8, 0 },
                         { 9, 0, 0, 8, 6, 3, 0, 0, 5 },
                         { 0, 5, 0, 0, 9, 0, 6, 0, 0 },
                         { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
                         { 0, 0, 0, 0, 0, 0, 0, 7, 4 },
                         { 0, 0, 5, 2, 0, 6, 3, 0, 0 } };
 
        if (solveSudoku(grid, 0, 0))
            print(grid);
        else
            System.out.println("No Solution exists");
    }
    // This is code is contributed by Pradeep Mondal P
}


Python3




# N is the size of the 2D matrix   N*N
N = 9
 
# A utility function to print grid
def printing(arr):
    for i in range(N):
        for j in range(N):
            print(arr[i][j], end = " ")
        print()
 
# Checks whether it will be
# legal to assign num to the
# given row, col
def isSafe(grid, row, col, num):
   
    # Check if we find the same num
    # in the similar row , we
    # return false
    for x in range(9):
        if grid[row][x] == num:
            return False
 
    # Check if we find the same num in
    # the similar column , we
    # return false
    for x in range(9):
        if grid[x][col] == num:
            return False
 
    # Check if we find the same num in
    # the particular 3*3 matrix,
    # we return false
    startRow = row - row % 3
    startCol = col - col % 3
    for i in range(3):
        for j in range(3):
            if grid[i + startRow][j + startCol] == num:
                return False
    return True
 
# Takes a partially filled-in grid and attempts
# to assign values to all unassigned locations in
# such a way to meet the requirements for
# Sudoku solution (non-duplication across rows,
# columns, and boxes) */
def solveSudoku(grid, row, col):
   
    # Check if we have reached the 8th
    # row and 9th column (0
    # indexed matrix) , we are
    # returning true to avoid
    # further backtracking
    if (row == N - 1 and col == N):
        return True
       
    # Check if column value  becomes 9 ,
    # we move to next row and
    # column start from 0
    if col == N:
        row += 1
        col = 0
 
    # Check if the current position of
    # the grid already contains
    # value >0, we iterate for next column
    if grid[row][col] > 0:
        return solveSudoku(grid, row, col + 1)
    for num in range(1, N + 1, 1):
       
        # Check if it is safe to place
        # the num (1-9)  in the
        # given row ,col  ->we
        # move to next column
        if isSafe(grid, row, col, num):
           
            # Assigning the num in
            # the current (row,col)
            # position of the grid
            # and assuming our assigned
            # num in the position
            # is correct
            grid[row][col] = num
 
            # Checking for next possibility with next
            # column
            if solveSudoku(grid, row, col + 1):
                return True
 
        # Removing the assigned num ,
        # since our assumption
        # was wrong , and we go for
        # next assumption with
        # diff num value
        grid[row][col] = 0
    return False
 
# Driver Code
 
# 0 means unassigned cells
grid = [[3, 0, 6, 5, 0, 8, 4, 0, 0],
        [5, 2, 0, 0, 0, 0, 0, 0, 0],
        [0, 8, 7, 0, 0, 0, 0, 3, 1],
        [0, 0, 3, 0, 1, 0, 0, 8, 0],
        [9, 0, 0, 8, 6, 3, 0, 0, 5],
        [0, 5, 0, 0, 9, 0, 6, 0, 0],
        [1, 3, 0, 0, 0, 0, 2, 5, 0],
        [0, 0, 0, 0, 0, 0, 0, 7, 4],
        [0, 0, 5, 2, 0, 6, 3, 0, 0]]
 
if (solveSudoku(grid, 0, 0)):
    printing(grid)
else:
    print("no solution  exists ")
 
    # This code is contributed by sudhanshgupta2019a


C#




// C# program for above approach
using System;
class GFG {
 
  // N is the size of the 2D matrix   N*N
  static int N = 9;
 
  /* Takes a partially filled-in grid and attempts
    to assign values to all unassigned locations in
    such a way to meet the requirements for
    Sudoku solution (non-duplication across rows,
    columns, and boxes) */
  static bool solveSudoku(int[,] grid, int row,
                          int col)
  {
 
    /*if we have reached the 8th
           row and 9th column (0
           indexed matrix) ,
           we are returning true to avoid further
           backtracking       */
    if (row == N - 1 && col == N)
      return true;
 
    // Check if column value  becomes 9 ,
    // we move to next row
    // and column start from 0
    if (col == N) {
      row++;
      col = 0;
    }
 
    // Check if the current position
    // of the grid already
    // contains value >0, we iterate
    // for next column
    if (grid[row,col] != 0)
      return solveSudoku(grid, row, col + 1);
 
    for (int num = 1; num < 10; num++) {
 
      // Check if it is safe to place
      // the num (1-9)  in the
      // given row ,col ->we move to next column
      if (isSafe(grid, row, col, num)) {
 
        /*  assigning the num in the current
                (row,col)  position of the grid and
                assuming our assigned num in the position
                is correct */
        grid[row,col] = num;
 
        // Checking for next
        // possibility with next column
        if (solveSudoku(grid, row, col + 1))
          return true;
      }
      /* removing the assigned num , since our
               assumption was wrong , and we go for next
               assumption with diff num value   */
      grid[row,col] = 0;
    }
    return false;
  }
 
  /* A utility function to print grid */
  static void print(int[,] grid)
  {
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++)
        Console.Write(grid[i,j] + " ");
      Console.WriteLine();
    }
  }
 
  // Check whether it will be legal
  // to assign num to the
  // given row, col
  static bool isSafe(int[,] grid, int row, int col,
                     int num)
  {
 
    // Check if we find the same num
    // in the similar row , we
    // return false
    for (int x = 0; x <= 8; x++)
      if (grid[row,x] == num)
        return false;
 
    // Check if we find the same num
    // in the similar column ,
    // we return false
    for (int x = 0; x <= 8; x++)
      if (grid[x,col] == num)
        return false;
 
    // Check if we find the same num
    // in the particular 3*3
    // matrix, we return false
    int startRow = row - row % 3, startCol
      = col - col % 3;
    for (int i = 0; i < 3; i++)
      for (int j = 0; j < 3; j++)
        if (grid[i + startRow,j + startCol] == num)
          return false;
 
    return true;
  }
 
  // Driver code
  static void Main() {
    int[,] grid = { { 3, 0, 6, 5, 0, 8, 4, 0, 0 },
                   { 5, 2, 0, 0, 0, 0, 0, 0, 0 },
                   { 0, 8, 7, 0, 0, 0, 0, 3, 1 },
                   { 0, 0, 3, 0, 1, 0, 0, 8, 0 },
                   { 9, 0, 0, 8, 6, 3, 0, 0, 5 },
                   { 0, 5, 0, 0, 9, 0, 6, 0, 0 },
                   { 1, 3, 0, 0, 0, 0, 2, 5, 0 },
                   { 0, 0, 0, 0, 0, 0, 0, 7, 4 },
                   { 0, 0, 5, 2, 0, 6, 3, 0, 0 } };
 
    if (solveSudoku(grid, 0, 0))
      print(grid);
    else
      Console.WriteLine("No Solution exists");
  }
}
 
// This code is contributed by divyesh072019.


Javascript




<script>
 
// Javascript program for above approach
 
// N is the size of the 2D matrix   N*N
let N = 9;
 
/* Takes a partially filled-in grid and attempts
    to assign values to all unassigned locations in
    such a way to meet the requirements for
    Sudoku solution (non-duplication across rows,
    columns, and boxes) */
function solveSudoku(grid, row, col)
{
     
    /* If we have reached the 8th
       row and 9th column (0
       indexed matrix) ,
       we are returning true to avoid further
       backtracking       */
    if (row == N - 1 && col == N)
        return true;
 
    // Check if column value  becomes 9 ,
    // we move to next row
    // and column start from 0
    if (col == N)
    {
        row++;
        col = 0;
    }
 
    // Check if the current position
    // of the grid already
    // contains value >0, we iterate
    // for next column
    if (grid[row][col] != 0)
        return solveSudoku(grid, row, col + 1);
 
    for(let num = 1; num < 10; num++)
    {
         
        // Check if it is safe to place
        // the num (1-9)  in the given
        // row ,col ->we move to next column
        if (isSafe(grid, row, col, num))
        {
             
            /*  assigning the num in the current
            (row,col)  position of the grid and
            assuming our assigned num in the position
            is correct */
            grid[row][col] = num;
 
            // Checking for next
            // possibility with next column
            if (solveSudoku(grid, row, col + 1))
                return true;
        }
         
        /* removing the assigned num , since our
           assumption was wrong , and we go for next
           assumption with diff num value   */
        grid[row][col] = 0;
    }
    return false;
}
 
/* A utility function to print grid */
function print(grid)
{
    for(let i = 0; i < N; i++)
    {
        for(let j = 0; j < N; j++)
            document.write(grid[i][j] + " ");
             
        document.write("<br>");
    }
}
 
// Check whether it will be legal
// to assign num to the
// given row, col
function isSafe(grid, row, col, num)
{
     
    // Check if we find the same num
    // in the similar row , we
    // return false
    for(let x = 0; x <= 8; x++)
        if (grid[row][x] == num)
            return false;
 
    // Check if we find the same num
    // in the similar column ,
    // we return false
    for(let x = 0; x <= 8; x++)
        if (grid[x][col] == num)
            return false;
 
    // Check if we find the same num
    // in the particular 3*3
    // matrix, we return false
    let startRow = row - row % 3,
        startCol = col - col % 3;
         
    for(let i = 0; i < 3; i++)
        for(let j = 0; j < 3; j++)
            if (grid[i + startRow][j + startCol] == num)
                return false;
 
    return true;
}
 
// Driver Code
let grid = [ [ 3, 0, 6, 5, 0, 8, 4, 0, 0 ],
             [ 5, 2, 0, 0, 0, 0, 0, 0, 0 ],
             [ 0, 8, 7, 0, 0, 0, 0, 3, 1 ],
             [ 0, 0, 3, 0, 1, 0, 0, 8, 0 ],
             [ 9, 0, 0, 8, 6, 3, 0, 0, 5 ],
             [ 0, 5, 0, 0, 9, 0, 6, 0, 0 ],
             [ 1, 3, 0, 0, 0, 0, 2, 5, 0 ],
             [ 0, 0, 0, 0, 0, 0, 0, 7, 4 ],
             [ 0, 0, 5, 2, 0, 6, 3, 0, 0 ] ]
  
if (solveSudoku(grid, 0, 0))
    print(grid)
else
    document.write("no solution  exists ")
 
// This code is contributed by rag2127
 
</script>


Output

3 1 6 5 7 8 4 9 2 
5 2 9 1 3 4 7 6 8 
4 8 7 6 2 9 5 3 1 
2 6 3 4 1 5 9 8 7 
9 7 4 8 6 3 1 2 5 
8 5 1 7 9 2 6 4 3 
1 3 8 9 4 7 2 5 6 
6 9 2 3 5 1 8 7 4 
7 4 5 2 8 6 3 1 9

Time complexity: O(9(N*N)), For every unassigned index, there are 9 possible options so the time complexity is O(9^(n*n)).
Space Complexity: O(N*N), To store the output array a matrix is needed.

Similar Reads

Sudoku using Backtracking:

...

Sudoku using Bit Masks:

...

Sudoku using Cross-Hatching with backtracking:

...

Contact Us