Given an incomplete Sudoku in the form of matrix mat[][] of order 9*9, the task is to complete the Sudoku. A sudoku solution must satisfy all of the following rules:
Each of the digits 1-9 must occur exactly once in each row.
Each of the digits 1-9 must occur exactly once in each column.
Each of the digits 1-9 must occur exactly once in each of the 9, 3x3 sub-boxes of the grid.
Note: Zeros in the mat[][] indicate blanks, which are to be filled with some number between 1 to 9. You can not replace the element in the cell which is not blank.
Examples:
Input:
Output:
Explanation: Each row, column and 3*3 box of the output matrix contains unique numbers.
[Naive Approach] Using Backtracking
The idea is to use backtracking and recursivelygenerate all possible configurations of numbers from 1 to 9 to fill the empty cells of matrix mat[][]. To do so, for every unassigned cell, fill the cell with a number from 1 to 9 one by one. After filling the unassigned cell check if the matrix is safe or not. If safe, move to the next cell else backtrack for other cases.
To check if it is safe to place value num in the cell mat[i][j], iterate through all the columns of row i, rows of column j and the 3*3 matrix containing cell (i, j) and check if they already has value num, if so return false, else return true.
C++
// C++ Program to solve Sudoku problem#include<iostream>#include<vector>usingnamespacestd;// Function to check if it is safe to place num at mat[row][col]boolisSafe(vector<vector<int>>&mat,introw,intcol,intnum){// Check if num exist in the rowfor(intx=0;x<=8;x++)if(mat[row][x]==num)returnfalse;// Check if num exist in the colfor(intx=0;x<=8;x++)if(mat[x][col]==num)returnfalse;// Check if num exist in the 3x3 sub-matrixintstartRow=row-(row%3),startCol=col-(col%3);for(inti=0;i<3;i++)for(intj=0;j<3;j++)if(mat[i+startRow][j+startCol]==num)returnfalse;returntrue;}// Function to solve the Sudoku problemboolsolveSudokuRec(vector<vector<int>>&mat,introw,intcol){intn=mat.size();// base case: Reached nth column of last rowif(row==n-1&&col==n)returntrue;// If last column of the row go to next rowif(col==n){row++;col=0;}// If cell is already occupied then move forwardif(mat[row][col]!=0)returnsolveSudokuRec(mat,row,col+1);for(intnum=1;num<=n;num++){// If it is safe to place num at current positionif(isSafe(mat,row,col,num)){mat[row][col]=num;if(solveSudokuRec(mat,row,col+1))returntrue;mat[row][col]=0;}}returnfalse;}voidsolveSudoku(vector<vector<int>>&mat){solveSudokuRec(mat,0,0);}intmain(){vector<vector<int>>mat={{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}};solveSudoku(mat);for(inti=0;i<mat.size();i++){for(intj=0;j<mat.size();j++)cout<<mat[i][j]<<" ";cout<<endl;}return0;}
Java
// Java Program to solve Sudoku problemimportjava.util.Arrays;classGfG{// Function to check if it is safe to place num at mat[row][col]staticbooleanisSafe(int[][]mat,introw,intcol,intnum){// Check if num exists in the rowfor(intx=0;x<9;x++)if(mat[row][x]==num)returnfalse;// Check if num exists in the colfor(intx=0;x<9;x++)if(mat[x][col]==num)returnfalse;// Check if num exists in the 3x3 sub-matrixintstartRow=row-(row%3),startCol=col-(col%3);for(inti=0;i<3;i++)for(intj=0;j<3;j++)if(mat[i+startRow][j+startCol]==num)returnfalse;returntrue;}// Function to solve the Sudoku problemstaticbooleansolveSudokuRec(int[][]mat,introw,intcol){// base case: Reached nth column of the last rowif(row==8&&col==9)returntrue;// If last column of the row go to the next rowif(col==9){row++;col=0;}// If cell is already occupied then move forwardif(mat[row][col]!=0)returnsolveSudokuRec(mat,row,col+1);for(intnum=1;num<=9;num++){// If it is safe to place num at current positionif(isSafe(mat,row,col,num)){mat[row][col]=num;if(solveSudokuRec(mat,row,col+1))returntrue;mat[row][col]=0;}}returnfalse;}staticvoidsolveSudoku(int[][]mat){solveSudokuRec(mat,0,0);}publicstaticvoidmain(String[]args){int[][]mat={{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}};solveSudoku(mat);for(inti=0;i<mat.length;i++){for(intj=0;j<mat[i].length;j++)System.out.print(mat[i][j]+" ");System.out.println();}}}
Python
# Python Program to solve Sudoku problem# Function to check if it is safe to place num at mat[row][col]defisSafe(mat,row,col,num):# Check if num exists in the rowforxinrange(9):ifmat[row][x]==num:returnFalse# Check if num exists in the colforxinrange(9):ifmat[x][col]==num:returnFalse# Check if num exists in the 3x3 sub-matrixstartRow=row-(row%3)startCol=col-(col%3)foriinrange(3):forjinrange(3):ifmat[i+startRow][j+startCol]==num:returnFalsereturnTrue# Function to solve the Sudoku problemdefsolveSudokuRec(mat,row,col):# base case: Reached nth column of the last rowifrow==8andcol==9:returnTrue# If last column of the row go to the next rowifcol==9:row+=1col=0# If cell is already occupied then move forwardifmat[row][col]!=0:returnsolveSudokuRec(mat,row,col+1)fornuminrange(1,10):# If it is safe to place num at current positionifisSafe(mat,row,col,num):mat[row][col]=numifsolveSudokuRec(mat,row,col+1):returnTruemat[row][col]=0returnFalsedefsolveSudoku(mat):solveSudokuRec(mat,0,0)if__name__=="__main__":mat=[[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]]solveSudoku(mat)forrowinmat:print(" ".join(map(str,row)))
C#
// C# Program to solve Sudoku problemusingSystem;classGfG{// Function to check if it is safe to place num at mat[row][col]staticboolisSafe(int[,]mat,introw,intcol,intnum){// Check if num exists in the rowfor(intx=0;x<9;x++)if(mat[row,x]==num)returnfalse;// Check if num exists in the colfor(intx=0;x<9;x++)if(mat[x,col]==num)returnfalse;// Check if num exists in the 3x3 sub-matrixintstartRow=row-(row%3),startCol=col-(col%3);for(inti=0;i<3;i++)for(intj=0;j<3;j++)if(mat[i+startRow,j+startCol]==num)returnfalse;returntrue;}// Function to solve the Sudoku problemstaticboolsolveSudokuRec(int[,]mat,introw,intcol){// base case: Reached nth column of the last rowif(row==8&&col==9)returntrue;// If last column of the row go to the next rowif(col==9){row++;col=0;}// If cell is already occupied then move forwardif(mat[row,col]!=0)returnsolveSudokuRec(mat,row,col+1);for(intnum=1;num<=9;num++){// If it is safe to place num at current positionif(isSafe(mat,row,col,num)){mat[row,col]=num;if(solveSudokuRec(mat,row,col+1))returntrue;mat[row,col]=0;}}returnfalse;}staticvoidsolveSudoku(int[,]mat){solveSudokuRec(mat,0,0);}publicstaticvoidMain(){int[,]mat={{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}};solveSudoku(mat);for(inti=0;i<9;i++){for(intj=0;j<9;j++)Console.Write(mat[i,j]+" ");Console.WriteLine();}}}
JavaScript
// JavaScript Program to solve Sudoku problem// Function to check if it is safe to place num at mat[row][col]functionisSafe(mat,row,col,num){// Check if num exists in the rowfor(letx=0;x<9;x++)if(mat[row][x]===num)returnfalse;// Check if num exists in the colfor(letx=0;x<9;x++)if(mat[x][col]===num)returnfalse;// Check if num exists in the 3x3 sub-matrixconststartRow=row-(row%3),startCol=col-(col%3);for(leti=0;i<3;i++)for(letj=0;j<3;j++)if(mat[i+startRow][j+startCol]===num)returnfalse;returntrue;}// Function to solve the Sudoku problemfunctionsolveSudokuRec(mat,row,col){// base case: Reached nth column of the last rowif(row===8&&col===9)returntrue;// If last column of the row go to the next rowif(col===9){row++;col=0;}// If cell is already occupied then move forwardif(mat[row][col]!==0)returnsolveSudokuRec(mat,row,col+1);for(letnum=1;num<=9;num++){// If it is safe to place num at current positionif(isSafe(mat,row,col,num)){mat[row][col]=num;if(solveSudokuRec(mat,row,col+1))returntrue;mat[row][col]=0;}}returnfalse;}functionsolveSudoku(mat){solveSudokuRec(mat,0,0);}// Driver Codeconstmat=[[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]];solveSudoku(mat);mat.forEach(row=>console.log(row.join(" ")));
Time complexity: O(n*9(n*n)), For every unassigned index, there are 9 possible options and for each index, we are checking other columns, rows and boxes. Auxiliary Space: O(1)
[Expected Approach] Using Bit Masking with Backtracking - O(9(n*n)) Time and O(n) Space
In the above approach, isSafe() function which is used to check if it is safe to place number num in cell (i, j) searches for num in each row, col and box. The idea is to optimize this using Bit Masking. To do so, create three arrays rows[], cols[], boxs[] of size n to mark the used value in row, column and box respectively. The element row[i] marks the number already been used in row i, and so do cols[] and boxs[] for columns and boxes. To mark the number num of row i, set the bit num from left of row[i] and operate similarly for cols[] and boxs[]. Similarly, to unmark the value num, unset the bits set in current step.
C++
// C++ Program to solve Sudoku problem#include<iostream>#include<vector>usingnamespacestd;// Function to heck if it is safe to place num at mat[row][col]boolisSafe(vector<vector<int>>&mat,inti,intj,intnum,vector<int>&row,vector<int>&col,vector<int>&box){if((row[i]&(1<<num))||(col[j]&(1<<num))||(box[i/3*3+j/3]&(1<<num)))returnfalse;returntrue;}boolsudokuSolverRec(vector<vector<int>>&mat,inti,intj,vector<int>&row,vector<int>&col,vector<int>&box){intn=mat.size();// base case: Reached nth column of last rowif(i==n-1&&j==n)returntrue;// If reached last column of the row go to next rowif(j==n){i++;j=0;}// If cell is already occupied then move forwardif(mat[i][j]!=0)returnsudokuSolverRec(mat,i,j+1,row,col,box);for(intnum=1;num<=n;num++){// If it is safe to place num at current positionif(isSafe(mat,i,j,num,row,col,box)){mat[i][j]=num;// Update masks for the corresponding row, column and boxrow[i]|=(1<<num);col[j]|=(1<<num);box[i/3*3+j/3]|=(1<<num);if(sudokuSolverRec(mat,i,j+1,row,col,box))returntrue;// Unmask the number num in the corresponding row, column and box masksmat[i][j]=0;row[i]&=~(1<<num);col[j]&=~(1<<num);box[i/3*3+j/3]&=~(1<<num);}}returnfalse;}voidsolveSudoku(vector<vector<int>>&mat){intn=mat.size();vector<int>row(n,0),col(n,0),box(n,0);// Set the bits in bitmasks for values that are initital present for(inti=0;i<n;i++){for(intj=0;j<n;j++){if(mat[i][j]!=0){row[i]|=(1<<mat[i][j]);col[j]|=(1<<mat[i][j]);box[(i/3)*3+j/3]|=(1<<mat[i][j]);}}}sudokuSolverRec(mat,0,0,row,col,box);}intmain(){vector<vector<int>>mat={{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}};solveSudoku(mat);for(inti=0;i<mat.size();i++){for(intj=0;j<mat.size();j++)cout<<mat[i][j]<<" ";cout<<endl;}return0;}
Java
// Java Program to solve Sudoku problemimportjava.util.Arrays;classGfG{// Function to check if it is safe to place num at mat[row][col]staticbooleanisSafe(int[][]mat,inti,intj,intnum,int[]row,int[]col,int[]box){if((row[i]&(1<<num))!=0||(col[j]&(1<<num))!=0||(box[i/3*3+j/3]&(1<<num))!=0)returnfalse;returntrue;}staticbooleansudokuSolverRec(int[][]mat,inti,intj,int[]row,int[]col,int[]box){intn=mat.length;// base case: Reached nth column of last rowif(i==n-1&&j==n)returntrue;// If reached last column of the row go to next rowif(j==n){i++;j=0;}// If cell is already occupied then move forwardif(mat[i][j]!=0)returnsudokuSolverRec(mat,i,j+1,row,col,box);for(intnum=1;num<=n;num++){// If it is safe to place num at current positionif(isSafe(mat,i,j,num,row,col,box)){mat[i][j]=num;// Update masks for the corresponding row, column and boxrow[i]|=(1<<num);col[j]|=(1<<num);box[i/3*3+j/3]|=(1<<num);if(sudokuSolverRec(mat,i,j+1,row,col,box))returntrue;// Unmask the number num in the corresponding row, column and box masksmat[i][j]=0;row[i]&=~(1<<num);col[j]&=~(1<<num);box[i/3*3+j/3]&=~(1<<num);}}returnfalse;}staticvoidsolveSudoku(int[][]mat){intn=mat.length;int[]row=newint[n];int[]col=newint[n];int[]box=newint[n];// Set the bits in bitmasks for values that are initially presentfor(inti=0;i<n;i++){for(intj=0;j<n;j++){if(mat[i][j]!=0){row[i]|=(1<<mat[i][j]);col[j]|=(1<<mat[i][j]);box[(i/3)*3+j/3]|=(1<<mat[i][j]);}}}sudokuSolverRec(mat,0,0,row,col,box);}publicstaticvoidmain(String[]args){int[][]mat={{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}};solveSudoku(mat);for(inti=0;i<mat.length;i++){for(intj=0;j<mat[i].length;j++)System.out.print(mat[i][j]+" ");System.out.println();}}}
Python
# Python Program to solve Sudoku problemdefisSafe(mat,i,j,num,row,col,box):if(row[i]&(1<<num))or(col[j]&(1<<num))or(box[i//3*3+j//3]&(1<<num)):returnFalsereturnTruedefsudokuSolverRec(mat,i,j,row,col,box):n=len(mat)# base case: Reached nth column of last rowifi==n-1andj==n:returnTrue# If reached last column of the row go to next rowifj==n:i+=1j=0# If cell is already occupied then move forwardifmat[i][j]!=0:returnsudokuSolverRec(mat,i,j+1,row,col,box)fornuminrange(1,n+1):# If it is safe to place num at current positionifisSafe(mat,i,j,num,row,col,box):mat[i][j]=num# Update masks for the corresponding row, column and boxrow[i]|=(1<<num)col[j]|=(1<<num)box[i//3*3+j//3]|=(1<<num)ifsudokuSolverRec(mat,i,j+1,row,col,box):returnTrue# Unmask the number num in the corresponding row, column and box masksmat[i][j]=0row[i]&=~(1<<num)col[j]&=~(1<<num)box[i//3*3+j//3]&=~(1<<num)returnFalsedefsolveSudoku(mat):n=len(mat)row=[0]*ncol=[0]*nbox=[0]*n# Set the bits in bitmasks for values that are initially presentforiinrange(n):forjinrange(n):ifmat[i][j]!=0:row[i]|=(1<<mat[i][j])col[j]|=(1<<mat[i][j])box[(i//3)*3+j//3]|=(1<<mat[i][j])sudokuSolverRec(mat,0,0,row,col,box)if__name__=="__main__":mat=[[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]]solveSudoku(mat)forrowinmat:print(" ".join(map(str,row)))
C#
// C# Program to solve Sudoku problem using bitmasksusingSystem;classGfG{// Function to check if it is safe to place num at mat[row, col]staticboolisSafe(int[,]mat,inti,intj,intnum,int[]row,int[]col,int[]box){if((row[i]&(1<<num))!=0||(col[j]&(1<<num))!=0||(box[i/3*3+j/3]&(1<<num))!=0)returnfalse;returntrue;}staticboolsudokuSolverRec(int[,]mat,inti,intj,int[]row,int[]col,int[]box){intn=mat.GetLength(0);// base case: Reached nth column of last rowif(i==n-1&&j==n)returntrue;// If reached last column of the row, go to next rowif(j==n){i++;j=0;}// If cell is already occupied, then move forwardif(mat[i,j]!=0)returnsudokuSolverRec(mat,i,j+1,row,col,box);for(intnum=1;num<=n;num++){// If it is safe to place num at current positionif(isSafe(mat,i,j,num,row,col,box)){mat[i,j]=num;// Update masks for the corresponding row, column, and boxrow[i]|=(1<<num);col[j]|=(1<<num);box[i/3*3+j/3]|=(1<<num);if(sudokuSolverRec(mat,i,j+1,row,col,box))returntrue;// Unmask the number num in the corresponding row, column and box masksmat[i,j]=0;row[i]&=~(1<<num);col[j]&=~(1<<num);box[i/3*3+j/3]&=~(1<<num);}}returnfalse;}staticvoidsolveSudoku(int[,]mat){intn=mat.GetLength(0);int[]row=newint[n];int[]col=newint[n];int[]box=newint[n];// Set the bits in bitmasks for values that are initially presentfor(inti=0;i<n;i++){for(intj=0;j<n;j++){if(mat[i,j]!=0){row[i]|=(1<<mat[i,j]);col[j]|=(1<<mat[i,j]);box[(i/3)*3+j/3]|=(1<<mat[i,j]);}}}sudokuSolverRec(mat,0,0,row,col,box);}publicstaticvoidMain(string[]args){int[,]mat={{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}};solveSudoku(mat);for(inti=0;i<mat.GetLength(0);i++){for(intj=0;j<mat.GetLength(1);j++)Console.Write(mat[i,j]+" ");Console.WriteLine();}}}
JavaScript
// JavaScript Program to solve Sudoku problem using bitmasks// Function to check if it is safe to place num at mat[row][col]functionisSafe(mat,i,j,num,row,col,box){if((row[i]&(1<<num))!==0||(col[j]&(1<<num))!==0||(box[Math.floor(i/3)*3+Math.floor(j/3)]&(1<<num))!==0)returnfalse;returntrue;}functionsudokuSolverRec(mat,i,j,row,col,box){constn=mat.length;// base case: Reached nth column of last rowif(i===n-1&&j===n)returntrue;// If reached last column of the row, go to next rowif(j===n){i++;j=0;}// If cell is already occupied, then move forwardif(mat[i][j]!==0)returnsudokuSolverRec(mat,i,j+1,row,col,box);for(letnum=1;num<=n;num++){// If it is safe to place num at current positionif(isSafe(mat,i,j,num,row,col,box)){mat[i][j]=num;// Update masks for the corresponding row, column, and boxrow[i]|=(1<<num);col[j]|=(1<<num);box[Math.floor(i/3)*3+Math.floor(j/3)]|=(1<<num);if(sudokuSolverRec(mat,i,j+1,row,col,box))returntrue;// Unmask the number num in the corresponding row, column and box masksmat[i][j]=0;row[i]&=~(1<<num);col[j]&=~(1<<num);box[Math.floor(i/3)*3+Math.floor(j/3)]&=~(1<<num);}}returnfalse;}functionsolveSudoku(mat){constn=mat.length;constrow=newArray(n).fill(0);constcol=newArray(n).fill(0);constbox=newArray(n).fill(0);// Set the bits in bitmasks for values that are initially presentfor(leti=0;i<n;i++){for(letj=0;j<n;j++){if(mat[i][j]!==0){row[i]|=(1<<mat[i][j]);col[j]|=(1<<mat[i][j]);box[Math.floor(i/3)*3+Math.floor(j/3)]|=(1<<mat[i][j]);}}}sudokuSolverRec(mat,0,0,row,col,box);}// Driver Codeconstmat=[[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]];solveSudoku(mat);for(leti=0;i<mat.length;i++){console.log(mat[i].join(" "));}
We use cookies to ensure you have the best browsing experience on our website. By using our site, you
acknowledge that you have read and understood our
Cookie Policy &
Privacy Policy
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.