Given a solution of Sudoku puzzle, the task is to check whether the given sudoku solution is valid or not. A valid solution requires that each row, column, and 3×3 sub-matrix must contain the digits 1-9 without repetition.
Examples:
Input:
Output: true Explanation: This sudoku solution is valid.
In our previous article, we discussed how to check whether a Sudoku board configuration is valid. And for this problem, the approach remains the same. However, while that article focused on validating configurations, here we will be validating a complete Sudoku solution.
Using Array of Fixed Length
To check whether a given sudoku solution is valid or not. We have to make sure that each number (1-9) appears only once per row, column, and 3x3 sub-matrix. We can use array or hash table for keeping track of seen/visited elements, Here we have used auxiliary arrays to track the seen/visited of each number in rows, columns, and sub-matrix.
Step-by-step approach:
We use three 2D arrays (rows, cols, subMat) to track which numbers have already appeared in each row, column, and sub-matrix, respectively.
For each cell, we skip if it contains 0 (empty). Otherwise, we check if the number has already appeared in the corresponding row, column, or sub-matrix. If so, the matrix is invalid.
The sub-matrix index is calculated as (i / 3) * 3 + j / 3 where i and j are the row and column indices.
If the current number is not visited before in the current row, column, or sub-matrix then marked as seen/visited.
C++
#include<bits/stdc++.h>usingnamespacestd;// Function to check if the Sudoku matrix is validintisValid(vector<vector<int>>mat){// Track of numbers in rows, columns, and sub-matrixvector<vector<int>>rows(10,vector<int>(10,0));vector<vector<int>>cols(10,vector<int>(10,0));vector<vector<int>>subMat(10,vector<int>(10,0));for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Skip empty cellsif(mat[i][j]==0)continue;// Current valueintval=mat[i][j];// Check for duplicates in rowif(rows[i][val]==1)returnfalse;// Mark as seenrows[i][val]=1;// Check for duplicates in columnif(cols[j][val]==1)returnfalse;// Mark as seencols[j][val]=1;// Check for duplicates in sub-gridintidx=(i/3)*3+j/3;if(subMat[idx][val]==1)returnfalse;// Mark as seensubMat[idx][val]=1;}}returntrue;}intmain(){vector<vector<int>>mat={{7,9,2,1,5,4,3,8,6},{6,4,3,8,2,7,1,5,9},{8,5,1,3,9,6,7,2,4},{2,6,5,9,7,3,8,4,1},{4,8,9,5,6,1,2,7,3},{3,1,7,4,8,2,9,6,5},{1,3,6,7,4,8,5,9,2},{9,7,4,2,1,5,6,3,8},{5,2,8,6,3,9,4,1,7}};cout<<(isValid(mat)?"true":"false")<<"\n";return0;}
C
#include<stdio.h>#include<stdbool.h>intisValid(intmat[9][9]){// Track of numbers in rows, columns, and sub-matrixintrows[10][10]={0};intcols[10][10]={0};intsubMat[10][10]={0};for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Skip empty cellsif(mat[i][j]==0)continue;// Current valueintval=mat[i][j];// Check for duplicates in rowif(rows[i][val]==1)returnfalse;// false// Mark as seenrows[i][val]=1;// Check for duplicates in columnif(cols[j][val]==1)returnfalse;// false// Mark as seencols[j][val]=1;// Check for duplicates in sub-gridintidx=(i/3)*3+j/3;if(subMat[idx][val]==1)return0;// Mark as seensubMat[idx][val]=1;}}returntrue;}intmain(){intmat[9][9]={{7,9,2,1,5,4,3,8,6},{6,4,3,8,2,7,1,5,9},{8,5,1,3,9,6,7,2,4},{2,6,5,9,7,3,8,4,1},{4,8,9,5,6,1,2,7,3},{3,1,7,4,8,2,9,6,5},{1,3,6,7,4,8,5,9,2},{9,7,4,2,1,5,6,3,8},{5,2,8,6,3,9,4,1,7}};printf("%s\n",isValid(mat)?"true":"false");return0;}
Java
classGfG{staticbooleanisValid(int[][]mat){// Track of numbers in rows, columns, and sub-matrixint[][]rows=newint[10][10];int[][]cols=newint[10][10];int[][]subMat=newint[10][10];for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Skip empty cellsif(mat[i][j]==0)continue;// Current valueintval=mat[i][j];// Check for duplicates in rowif(rows[i][val]==1)returnfalse;// Mark as seenrows[i][val]=1;// Check for duplicates in columnif(cols[j][val]==1)returnfalse;// Mark as seencols[j][val]=1;// Check for duplicates in sub-gridintidx=(i/3)*3+j/3;if(subMat[idx][val]==1)returnfalse;// Mark as seensubMat[idx][val]=1;}}returntrue;}publicstaticvoidmain(String[]args){int[][]mat={{7,9,2,1,5,4,3,8,6},{6,4,3,8,2,7,1,5,9},{8,5,1,3,9,6,7,2,4},{2,6,5,9,7,3,8,4,1},{4,8,9,5,6,1,2,7,3},{3,1,7,4,8,2,9,6,5},{1,3,6,7,4,8,5,9,2},{9,7,4,2,1,5,6,3,8},{5,2,8,6,3,9,4,1,7}};System.out.println(isValid(mat)?"true":"false");}}
Python
defisValid(mat):# Track of numbers in rows, columns, and sub-matrixrows=[[0]*10for_inrange(10)]cols=[[0]*10for_inrange(10)]subMat=[[0]*10for_inrange(10)]foriinrange(9):forjinrange(9):# Skip empty cellsifmat[i][j]==0:continue# Current valueval=mat[i][j]# Check for duplicates in rowifrows[i][val]==1:returnFalse# Mark as seenrows[i][val]=1# Check for duplicates in columnifcols[j][val]==1:returnFalse# Mark as seencols[j][val]=1# Check for duplicates in sub-grididx=(i//3)*3+j//3ifsubMat[idx][val]==1:returnFalse# Mark as seensubMat[idx][val]=1returnTruemat=[[7,9,2,1,5,4,3,8,6],[6,4,3,8,2,7,1,5,9],[8,5,1,3,9,6,7,2,4],[2,6,5,9,7,3,8,4,1],[4,8,9,5,6,1,2,7,3],[3,1,7,4,8,2,9,6,5],[1,3,6,7,4,8,5,9,2],[9,7,4,2,1,5,6,3,8],[5,2,8,6,3,9,4,1,7]];print("true"ifisValid(mat)else"false")
C#
usingSystem;usingSystem.Collections.Generic;classGfG{// Function to check if the Sudoku matrix is validstaticboolIsValid(int[,]mat){// Track of numbers in rows, columns, and sub-matrixint[,]rows=newint[9,10];int[,]cols=newint[9,10];int[,]subMat=newint[9,10];for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Skip empty cellsif(mat[i,j]==0)continue;// Current valueintval=mat[i,j];// Check for duplicates in rowif(rows[i,val]==1)returnfalse;// Mark as seenrows[i,val]=1;// Check for duplicates in columnif(cols[j,val]==1)returnfalse;// Mark as seencols[j,val]=1;// Check for duplicates in sub-gridintidx=(i/3)*3+j/3;if(subMat[idx,val]==1)returnfalse;// Mark as seensubMat[idx,val]=1;}}returntrue;}staticvoidMain(){int[,]mat={{7,9,2,1,5,4,3,8,6},{6,4,3,8,2,7,1,5,9},{8,5,1,3,9,6,7,2,4},{2,6,5,9,7,3,8,4,1},{4,8,9,5,6,1,2,7,3},{3,1,7,4,8,2,9,6,5},{1,3,6,7,4,8,5,9,2},{9,7,4,2,1,5,6,3,8},{5,2,8,6,3,9,4,1,7}};Console.WriteLine(IsValid(mat)?"true":"false");}}
Output
true
Time Complexity: O(n^2), where n is the size of the Sudoku matrix (i.e, 9). This is because we iterate through all n*n cells of the matrix. Auxiliary Space: O(n^2), due to the three 2D arrays (rows, cols, subMat) of size n*n
Using Bitmasking
In the previous approach, we used arrays to track which numbers have appeared in each row, column, and sub-matrix. Now, we can make this more efficient by using bit manipulation, we represent the presence of numbers with bits in an integer, which reduces memory usage and improves time complexity as well. The implementation steps remain the same as above approach, apart from checking and marking visited values in row, column and sub-matrix.
Step-by-step approach:
Use a single integer for each row, column, and sub-matrix. Each bit in the integer corresponds to a number.
For each cell, we can use bitwise AND (&) to check if a number's bit is already set. If it is, that means the number has appeared before and the Sudoku is invalid.
If the current cell value (i,e, mat[i][j]) is not set in the row, column, or sub-matrix then we have to set the bit for the number using bitwise OR operation (|=) to mark it visited.
C++
#include<bits/stdc++.h>usingnamespacestd;boolisValid(vector<vector<int>>&mat){// Arrays to track seen numbers in rows,// columns, and sub-matrixvector<int>rows(9);vector<int>cols(9);vector<int>subMat(9);for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Skip empty cellsif(mat[i][j]==0)continue;intval=mat[i][j];// Bit position for the current valueintpos=1<<(val-1);// Check for duplicates in the current rowif((rows[i]&pos)>0)returnfalse;// Mark the value as seen in the rowrows[i]|=pos;// Check for duplicates in the current columnif((cols[j]&pos)>0)returnfalse;// Mark the value as seen in the columncols[j]|=pos;// Calculate the index for the 3x3 sub-matrixintidx=(i/3)*3+j/3;// Check for duplicates in the current sub-matrixif((subMat[idx]&pos)>0)returnfalse;// Mark the value as seen in the sub-matrixsubMat[idx]|=pos;}}returntrue;}intmain(){vector<vector<int>>mat={{7,9,2,1,5,4,3,8,6},{6,4,3,8,2,7,1,5,9},{8,5,1,3,9,6,7,2,4},{2,6,5,9,7,3,8,4,1},{4,8,9,5,6,1,2,7,3},{3,1,7,4,8,2,9,6,5},{1,3,6,7,4,8,5,9,2},{9,7,4,2,1,5,6,3,8},{5,2,8,6,3,9,4,1,7}};cout<<(isValid(mat)?"true":"false")<<"\n";return0;}
C
#include<stdio.h>#include<stdbool.h>boolisValid(intmat[][9]){// Arrays to track seen numbers in rows,// columns, and sub-matrixintrows[9]={0},cols[9]={0},subMat[9]={0};for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Skip empty cellsif(mat[i][j]==0)continue;intval=mat[i][j];intpos=1<<(val-1);// Check for duplicates in the current rowif((rows[i]&pos)>0)returnfalse;rows[i]|=pos;// Check for duplicates in the current columnif((cols[j]&pos)>0)returnfalse;cols[j]|=pos;// Calculate the index for the 3x3 sub-matrixintidx=(i/3)*3+j/3;// Check for duplicates in the current sub-matrixif((subMat[idx]&pos)>0)returnfalse;subMat[idx]|=pos;}}returntrue;}intmain(){intmat[][9]={{7,9,2,1,5,4,3,8,6},{6,4,3,8,2,7,1,5,9},{8,5,1,3,9,6,7,2,4},{2,6,5,9,7,3,8,4,1},{4,8,9,5,6,1,2,7,3},{3,1,7,4,8,2,9,6,5},{1,3,6,7,4,8,5,9,2},{9,7,4,2,1,5,6,3,8},{5,2,8,6,3,9,4,1,7}};printf("%s\n",isValid(mat)?"true":"false");return0;}
Java
importjava.util.Arrays;classGfG{staticbooleanisValid(int[][]mat){// Arrays to track seen numbers in rows,// columns, and sub-matrixint[]rows=newint[9];int[]cols=newint[9];int[]subMat=newint[9];for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Skip empty cellsif(mat[i][j]==0)continue;intval=mat[i][j];intpos=1<<(val-1);// Check for duplicates in the current rowif((rows[i]&pos)>0)returnfalse;rows[i]|=pos;// Check for duplicates in the current columnif((cols[j]&pos)>0)returnfalse;cols[j]|=pos;// Calculate the index for the 3x3 sub-matrixintidx=(i/3)*3+j/3;// Check for duplicates in the current sub-matrixif((subMat[idx]&pos)>0)returnfalse;subMat[idx]|=pos;}}returntrue;}publicstaticvoidmain(String[]args){int[][]mat={{7,9,2,1,5,4,3,8,6},{6,4,3,8,2,7,1,5,9},{8,5,1,3,9,6,7,2,4},{2,6,5,9,7,3,8,4,1},{4,8,9,5,6,1,2,7,3},{3,1,7,4,8,2,9,6,5},{1,3,6,7,4,8,5,9,2},{9,7,4,2,1,5,6,3,8},{5,2,8,6,3,9,4,1,7}};System.out.println(isValid(mat)?"true":"false");}}
Python
defisValid(mat):# Arrays to track seen numbers in rows,# columns, and sub-matrixrows=[0]*9cols=[0]*9subMat=[0]*9foriinrange(9):forjinrange(9):# Skip empty cellsifmat[i][j]==0:continueval=mat[i][j]pos=1<<(val-1)# Check for duplicates in the current rowif(rows[i]&pos)>0:returnFalserows[i]|=pos# Check for duplicates in the current columnif(cols[j]&pos)>0:returnFalsecols[j]|=pos# Calculate the index for the 3x3 sub-matrixidx=(i//3)*3+j//3# Check for duplicates in the current sub-matrixif(subMat[idx]&pos)>0:returnFalsesubMat[idx]|=posreturnTrueif__name__=="__main__":mat=[[7,9,2,1,5,4,3,8,6],[6,4,3,8,2,7,1,5,9],[8,5,1,3,9,6,7,2,4],[2,6,5,9,7,3,8,4,1],[4,8,9,5,6,1,2,7,3],[3,1,7,4,8,2,9,6,5],[1,3,6,7,4,8,5,9,2],[9,7,4,2,1,5,6,3,8],[5,2,8,6,3,9,4,1,7]];print("true"ifisValid(mat)else"false")
C#
usingSystem;classGfG{staticboolIsValid(int[,]mat){// Arrays to track seen numbers in rows, columns,// and sub-matrixint[]rows=newint[9];int[]cols=newint[9];int[]subMat=newint[9];for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Skip empty cellsif(mat[i,j]==0)continue;intval=mat[i,j];// Bit position for the current valueintpos=1<<(val-1);// Check for duplicates in the current rowif((rows[i]&pos)>0)returnfalse;// Mark the value as seen in the rowrows[i]|=pos;// Check for duplicates in the current// columnif((cols[j]&pos)>0)returnfalse;// Mark the value as seen in the columncols[j]|=pos;// Calculate the index for the 3x3// sub-matrixintidx=(i/3)*3+j/3;// Check for duplicates in the current// sub-matrixif((subMat[idx]&pos)>0)returnfalse;// Mark the value as seen in the sub-matrixsubMat[idx]|=pos;}}returntrue;}staticvoidMain(){int[,]mat={{7,9,2,1,5,4,3,8,6},{6,4,3,8,2,7,1,5,9},{8,5,1,3,9,6,7,2,4},{2,6,5,9,7,3,8,4,1},{4,8,9,5,6,1,2,7,3},{3,1,7,4,8,2,9,6,5},{1,3,6,7,4,8,5,9,2},{9,7,4,2,1,5,6,3,8},{5,2,8,6,3,9,4,1,7}};Console.WriteLine(IsValid(mat)?"true":"false");}}
Output
true
Time Complexity: O(n^2), where n is the size of the Sudoku matrix (i.e, 9). This is because we iterate through all n*n cells of the matrix. Auxiliary Space: O(n), as we use three arrays (rows, cols, subMat), each of size n to track the seen numbers for rows, columns, and sub-matrix. Each array element holds an integer, which is used for bitwise operations.
For more details and explanations about the solutions, please refer to our previous article.