Given an incomplete Sudoku in the form of matrix mat[][] of order 9*9, 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.
The idea to solve Sudoku is to use backtracking, where we recursively try to fill the empty cells with numbers from 1 to 9. For every unassigned cell, we place a number and then check whether it is valid to place that number in the given row, column, and 3×3 subgrid. If it is valid, we move to the next cell; if not, we backtrack and try another number. This process continues until all cells are filled or no solution exists.
C++
#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
importjava.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
# 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#
usingSystem;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
// 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(9(n*n)), For every unassigned index, there are 9 possible options and for each index Auxiliary Space: O(1)
[Approach 2] Using Bit Masking with Backtracking - O(9(n*n)) Time and O(n) Space
We can solve this efficiently by using backtracking combined with bitmasking. The idea is simple: for every empty cell, we attempt to place numbers from 1 to 9 and move recursively to the next cell.
The key optimization lies in avoiding repeated scanning of the row, column, and 3×3 box each time we place a number. Instead, we maintain three bitmask arrays—rows, cols, and boxes. In these arrays, each bit indicates whether a particular number has already been used in that row, column, or box.
Before placing a number, we simply check the corresponding bits in O(1) time to determine if it is valid. If it is safe, we set the bits and continue with recursion. If the placement leads to a dead end, we backtrack by unsetting the bits and trying another option.
C++
#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
importjava.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
defisSafe(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#
usingSystem;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
// 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(" "));}