Given a Sudoku board configuration, check whether the given Sudoku board configuration is valid or not. A valid configuration requires that each row, column, and 3x3 sub-matrix must contain the digits 1-9 without repetition.
Examples:
Input:
Output: true Explanation: It is possible to have a proper sudoku.
[Naive Approach] Checking Constraints - Time O(n^3) and Space O(n)
Every number between 1 to 9 appears only once in every row, column and 3X3 sub-matrix of the sudoku. Check for every cell that it's value is appearing only once in it's row, column and 3X3 sub-matrix.
C++
#include<iostream>#include<vector>usingnamespacestd;// Checks for duplicates in the current rowboolvalidRow(vector<vector<int>>&mat,introw){vector<int>vis(10,0);for(inti=0;i<9;i++){// If the cell is not emptyif(mat[row][i]!=0){intval=mat[row][i];// If duplicate is foundif(vis[val]!=0)returnfalse;// Mark the number as visitedvis[val]++;}}returntrue;}// Checks for duplicates in the current columnboolcolValid(vector<vector<int>>&mat,intcol){// Visited array to track occurrencesvector<int>vis(10,0);for(inti=0;i<9;i++){// If the cell is not emptyif(mat[i][col]!=0){intval=mat[i][col];// If duplicate is foundif(vis[val]!=0)returnfalse;// Mark the number as visitedvis[val]++;}}returntrue;}// Checks for duplicates in // the current 3x3 submatrixboolsubMatValid(vector<vector<int>>&mat,intstartRow,intstartCol){// Visited array to track occurrencesvector<int>vis(10,0);for(introw=0;row<3;row++){for(intcol=0;col<3;col++){// Current element in the submatrixintcurr=mat[row+startRow][col+startCol];// If the cell is not emptyif(curr!=0){// If duplicate is foundif(vis[curr]!=0)returnfalse;// Mark the number as visitedvis[curr]++;}}}returntrue;}// Validates the Sudoku boardboolisValid(vector<vector<int>>&mat){for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Check if the row, column,// or submatrix is invalidif(!validRow(mat,i)||!colValid(mat,j)||!subMatValid(mat,i-i%3,j-j%3))returnfalse;}}returntrue;}intmain(){vector<vector<int>>mat={{9,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,5,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};cout<<(isValid(mat)?"true":"false")<<endl;return0;}
C
#include<stdbool.h>#include<stdio.h>#include<string.h>// Checks for duplicates in current rowboolvalidRow(intmat[9][9],introw){// Integer array for marking visitedintvis[10]={0};for(inti=0;i<9;i++){// If the cell is not emptyif(mat[row][i]!=0){// If duplicate is foundif(vis[mat[row][i]]!=0)returnfalse;// Mark occurrence in the visited arrayvis[mat[row][i]]++;}}returntrue;}// Checks for duplicates in current columnboolcolValid(intmat[9][9],intcol){// Integer array for hashingintvis[10]={0};// Loop through the columnfor(inti=0;i<9;i++){// If the cell is not emptyif(mat[i][col]!=0){// If duplicate is foundif(vis[mat[i][col]]!=0)returnfalse;// Mark occurrence in the hash arrayvis[mat[i][col]]++;}}returntrue;}// Checks for duplicates in // the current 3x3 submatrixboolsubMatValid(intmat[9][9],intstartRow,intstartCol){// Integer array for hashingintvis[10]={0};for(introw=0;row<3;row++){for(intcol=0;col<3;col++){// Current element in the submatrixintcurr=mat[row+startRow][col+startCol];// If the cell is not emptyif(curr!=0){// If duplicate is foundif(vis[curr]!=0)returnfalse;// Mark occurrence in the hash arrayvis[curr]++;}}}returntrue;}// Validates the Sudoku boardboolisValid(intmat[9][9]){for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Check if row, column, or submatrix is invalidif(!validRow(mat,i)||!colValid(mat,j)||!subMatValid(mat,i-i%3,j-j%3))returnfalse;}}returntrue;}intmain(){intmat[9][9]={{9,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,5,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};printf(isValid(mat)?"true\n":"false\n");return0;}
Java
classGfG{// Checks for duplicates in the current rowstaticbooleanvalidRow(int[][]mat,introw){// Visited array to track occurrencesint[]vis=newint[10];for(inti=0;i<9;i++){// If the cell is not emptyif(mat[row][i]!=0){intval=mat[row][i];// If duplicate is foundif(vis[val]!=0)returnfalse;// Mark the number as visitedvis[val]++;}}returntrue;}// Checks for duplicates in the current columnstaticbooleancolValid(int[][]mat,intcol){// Visited array to track occurrencesint[]vis=newint[10];for(inti=0;i<9;i++){// If the cell is not emptyif(mat[i][col]!=0){intval=mat[i][col];// If duplicate is foundif(vis[val]!=0)returnfalse;// Mark the number as visitedvis[val]++;}}returntrue;}// Checks for duplicates in // the current 3x3 submatrixstaticbooleansubMatValid(int[][]mat,intstartRow,intstartCol){// Visited array to track occurrencesint[]vis=newint[10];for(introw=0;row<3;row++){for(intcol=0;col<3;col++){// Current element in the submatrixintcurr=mat[row+startRow][col+startCol];// If the cell is not emptyif(curr!=0){// If duplicate is foundif(vis[curr]!=0)returnfalse;// Mark the number as visitedvis[curr]++;}}}returntrue;}// Validates the Sudoku boardstaticbooleanisValid(int[][]mat){for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Check if the row, column,// or submatrix is invalidif(!validRow(mat,i)||!colValid(mat,j)||!subMatValid(mat,i-i%3,j-j%3))returnfalse;}}returntrue;}publicstaticvoidmain(String[]args){int[][]mat={{9,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,5,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};System.out.println(isValid(mat)?"true":"false");}}
Python
# Checks for duplicates in the current rowdefvalidRow(mat,row):# Visited array to track occurrencesvis=[0]*10foriinrange(9):# If the cell is not emptyifmat[row][i]!=0:val=mat[row][i]# If duplicate is foundifvis[val]!=0:returnFalse# Mark the number as visitedvis[val]+=1returnTrue# Checks for duplicates in the current columndefcolValid(mat,col):# Visited array to track occurrencesvis=[0]*10foriinrange(9):# If the cell is not emptyifmat[i][col]!=0:val=mat[i][col]# If duplicate is foundifvis[val]!=0:returnFalse# Mark the number as visitedvis[val]+=1returnTrue# Checks for duplicates in the current 3x3 submatrixdefsubMatValid(mat,startRow,startCol):# Visited array to track occurrencesvis=[0]*10forrowinrange(3):forcolinrange(3):# Current element in the submatrixcurr=mat[row+startRow][col+startCol]# If the cell is not emptyifcurr!=0:# If duplicate is foundifvis[curr]!=0:returnFalse# Mark the number as visitedvis[curr]+=1returnTrue# Validates the Sudoku boarddefisValid(mat):foriinrange(9):forjinrange(9):# Check if the row, column, or submatrix is invalidifnotvalidRow(mat,i)ornotcolValid(mat,j)or \
notsubMatValid(mat,i-i%3,j-j%3):returnFalsereturnTrueif__name__=="__main__":mat=[[9,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,5,8,0,0,0,0,6,0],[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]]print("true"ifisValid(mat)else"false")
C#
usingSystem;classGfG{// Checks for duplicates in the current rowstaticboolValidRow(int[,]mat,introw){// Visited array to track occurrencesint[]vis=newint[10];for(inti=0;i<9;i++){// If the cell is not emptyif(mat[row,i]!=0){intval=mat[row,i];// If duplicate is foundif(vis[val]!=0)returnfalse;// Mark the number as visitedvis[val]++;}}returntrue;}// Checks for duplicates in the current columnstaticboolColValid(int[,]mat,intcol){// Visited array to track occurrencesint[]vis=newint[10];for(inti=0;i<9;i++){// If the cell is not emptyif(mat[i,col]!=0){intval=mat[i,col];// If duplicate is foundif(vis[val]!=0)returnfalse;// Mark the number as visitedvis[val]++;}}returntrue;}// Checks for duplicates in // current 3x3 submatrixstaticboolSubMatValid(int[,]mat,intstartRow,intstartCol){// Visited array to track occurrencesint[]vis=newint[10];for(introw=0;row<3;row++){for(intcol=0;col<3;col++){// Current element in the submatrixintcurr=mat[row+startRow,col+startCol];// If the cell is not emptyif(curr!=0){// If duplicate is foundif(vis[curr]!=0)returnfalse;// Mark the number as visitedvis[curr]++;}}}returntrue;}// Validates the Sudoku boardstaticboolIsValid(int[,]mat){for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Check if the row, column, or submatrix is// invalidif(!ValidRow(mat,i)||!ColValid(mat,j)||!SubMatValid(mat,i-i%3,j-j%3))returnfalse;}}returntrue;}staticvoidMain(){int[,]mat={{9,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,5,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};Console.WriteLine(IsValid(mat)?"true":"false");}}
JavaScript
// Checks for duplicates in the current rowfunctionvalidRow(mat,row){// Visited array to track occurrencesletvis=Array(10).fill(0);for(leti=0;i<9;i++){// If the cell is not emptyif(mat[row][i]!==0){letval=mat[row][i];// If duplicate is foundif(vis[val]!==0)returnfalse;// Mark the number as visitedvis[val]++;}}returntrue;}// Checks for duplicates in the current columnfunctioncolValid(mat,col){// Visited array to track occurrencesletvis=Array(10).fill(0);for(leti=0;i<9;i++){// If the cell is not emptyif(mat[i][col]!==0){letval=mat[i][col];// If duplicate is foundif(vis[val]!==0)returnfalse;// Mark the number as visitedvis[val]++;}}returntrue;}// Checks for duplicates in // the current 3x3 submatrixfunctionsubMatValid(mat,startRow,startCol){// Visited array to track occurrencesletvis=Array(10).fill(0);for(letrow=0;row<3;row++){for(letcol=0;col<3;col++){// Current element in the submatrixletcurr=mat[row+startRow][col+startCol];// If the cell is not emptyif(curr!==0){// If duplicate is foundif(vis[curr]!==0)returnfalse;// Mark the number as visitedvis[curr]++;}}}returntrue;}// Validates the Sudoku boardfunctionisValid(mat){for(leti=0;i<9;i++){for(letj=0;j<9;j++){// Check if the row, column, or submatrix is// invalidif(!validRow(mat,i)||!colValid(mat,j)||!subMatValid(mat,i-i%3,j-j%3))returnfalse;}}returntrue;}// Driver codeletmat=[[9,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,5,8,0,0,0,0,6,0],[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]];console.log(isValid(mat)?"true":"false");
Output
true
[Better Approach 1] Using Hashing - Time O(n^2) and Space O(n^2)
This approach improves the time complexity of the previous method, but with a trade-off in space complexity. We use an unordered set for each row, column, and sub-matrix to track the values we’ve already seen/visited.
As we iterate through the matrix and for each cell, we check if the current cell value already exists in the corresponding row, column, or sub-grid. If a duplicate is found, the Sudoku board is invalid. If no duplicates are found after checking all cells, the board configuration is valid.
Important Observation: There are 9 submatrix of size 3*3 exists in the sudoku matrix, so to find index of sub-matrix we can use the formula (i / 3) * 3 + j / 3, where i and j are the row and column indices.
C++
#include<iostream>#include<vector>usingnamespacestd;// Function to check if the Sudoku matrix is validintisValid(vector<vector<int>>&mat){// Arrays of unordered sets to keep track of seen// numbers in rows, columns, and subMatrixunordered_set<int>rows[9];unordered_set<int>cols[9];unordered_set<int>subMat[9];for(inti=0;i<9;i++){for(intj=0;j<9;j++){// Get the value at the current cellintval=mat[i][j];// For empty (0), skip to the next cellif(val==0)continue;// Check if the value already exists// in the current rowif(rows[i].find(val)!=rows[i].end()){// Duplicate found, return falsereturnfalse;}// Insert the value into the current row's setrows[i].insert(val);// Check if the value already exists// in the current columnif(cols[j].find(val)!=cols[j].end()){// Duplicate found, return falsereturnfalse;}// Insert the value into the current column's setcols[j].insert(val);// Calculate the index for the 3x3 boxintidx=(i/3)*3+j/3;// Check if the value already exists// in the current 3x3 boxif(subMat[idx].find(val)!=subMat[idx].end()){// Duplicate found, return falsereturnfalse;}// Insert the value into the current box's setsubMat[idx].insert(val);}}// If no duplicates were found, return truereturntrue;}intmain(){vector<vector<int>>mat={{9,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,5,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};cout<<(isValid(mat)?"true":"false")<<"\n";return0;}
Java
importjava.util.List;importjava.util.ArrayList;importjava.util.HashSet;classGfG{// Function to check if the Sudoku matrix is validstaticbooleanisValid(int[][]mat){// Lists of sets to track seen numbers in rows, columns, and subMatricesList<HashSet<Integer>>rows=newArrayList<>();List<HashSet<Integer>>cols=newArrayList<>();List<HashSet<Integer>>subMat=newArrayList<>();// Initialize the setsfor(inti=0;i<9;i++){rows.add(newHashSet<>());cols.add(newHashSet<>());subMat.add(newHashSet<>());}for(inti=0;i<9;i++){for(intj=0;j<9;j++){intval=mat[i][j];// Skip empty cellsif(val==0)continue;// Check for duplicates in the rowif(rows.get(i).contains(val))returnfalse;rows.get(i).add(val);// Check for duplicates in the columnif(cols.get(j).contains(val))returnfalse;cols.get(j).add(val);// Calculate the sub-matrix indexintidx=(i/3)*3+(j/3);// Check for duplicates in the sub-matrixif(subMat.get(idx).contains(val))returnfalse;subMat.get(idx).add(val);}}returntrue;}publicstaticvoidmain(String[]args){int[][]mat={{9,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,5,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};System.out.println(isValid(mat)?"true":"false");}}
Python
# Function to check if the Sudoku matrix is validdefisValid(mat):# Arrays of sets to track seen numbers in rows, colsrows=[set()for_inrange(9)]cols=[set()for_inrange(9)]subMat=[set()for_inrange(9)]# Loop through the Sudoku gridforiinrange(9):forjinrange(9):val=mat[i][j]# Skip empty cellsifval==0:continue# Check for duplicates in the rowifvalinrows[i]:returnFalserows[i].add(val)# Check for duplicates in the columnifvalincols[j]:returnFalsecols[j].add(val)# Calculate the sub-matrix indexidx=(i//3)*3+(j//3)# Check for duplicates in the sub-matrixifvalinsubMat[idx]:returnFalsesubMat[idx].add(val)returnTrueif__name__=="__main__":mat=[[9,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,5,8,0,0,0,0,6,0],[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]]# Check if the Sudoku matrix is validprint("true"ifisValid(mat)else"false")
C#
usingSystem;usingSystem.Collections.Generic;classGfG{// Function to check if the Sudoku matrix is validstaticboolIsValid(int[,]mat){// Arrays of sets to track seen numbers in rows,// colsHashSet<int>[]rows=newHashSet<int>[9];HashSet<int>[]cols=newHashSet<int>[9];HashSet<int>[]subMat=newHashSet<int>[9];// Initialize the setsfor(inti=0;i<9;i++){rows[i]=newHashSet<int>();cols[i]=newHashSet<int>();subMat[i]=newHashSet<int>();}for(inti=0;i<9;i++){for(intj=0;j<9;j++){intval=mat[i,j];// Skip empty cellsif(val==0)continue;// Check for duplicates in the rowif(rows[i].Contains(val))returnfalse;rows[i].Add(val);// Check for duplicates in the columnif(cols[j].Contains(val))returnfalse;cols[j].Add(val);// Calculate the sub-matrix indexintidx=(i/3)*3+j/3;// Check for duplicates in the sub-matrixif(subMat[idx].Contains(val))returnfalse;subMat[idx].Add(val);}}returntrue;}staticvoidMain(){int[,]mat={{9,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,5,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};Console.WriteLine(IsValid(mat)?"true":"false");}}
JavaScript
// Function to check if the Sudoku matrix is validfunctionisValid(mat){// Arrays to track seen numbers in rows, cols, and// subMatricesletrows=Array.from({length:9},()=>newSet());letcols=Array.from({length:9},()=>newSet());letsubMat=Array.from({length:9},()=>newSet());// Loop through the Sudoku gridfor(leti=0;i<9;i++){for(letj=0;j<9;j++){letval=mat[i][j];// Skip empty cellsif(val===0)continue;// Check for duplicates in the rowif(rows[i].has(val))returnfalse;rows[i].add(val);// Check for duplicates in the columnif(cols[j].has(val))returnfalse;cols[j].add(val);// Calculate the sub-matrix indexletidx=Math.floor(i/3)*3+Math.floor(j/3);// Check for duplicates in the sub-matrixif(subMat[idx].has(val))returnfalse;subMat[idx].add(val);}}returntrue;}// Driver codeletmat=[[9,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,5,8,0,0,0,0,6,0],[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]];console.log(isValid(mat)?"true":"false");
Output
true
[Better Approach 2] Using Array of Fixed Length - Time O(n^2) and Space O(n^2)
Instead of using any hash table for keeping track of seen/visited elements, We can use auxiliary arrays to track the seen/visited of each number in rows, columns, and sub-matrix. By using arrays, we can eliminate the overhead of hashing.
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<iostream>#include<vector>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={{5,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,9,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};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]={{5,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,9,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};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={{5,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,9,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};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]=1returnTrueif__name__=="__main__":mat=[[5,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,9,8,0,0,0,0,6,0],[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]]print("true"ifisValid(mat)else"false")
C#
usingSystem;classGfG{// Function to check if the Sudoku matrix is validstaticboolIsValid(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;}staticvoidMain(){int[,]mat={{5,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,9,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};Console.WriteLine(IsValid(mat)?"true":"false");}}
JavaScript
// Function to check if the Sudoku matrix is validfunctionisValid(mat){// Track numbers in rows, columns, and sub-matricesletrows=Array.from({length:9},()=>Array(10).fill(0));letcols=Array.from({length:9},()=>Array(10).fill(0));letsubMat=Array.from({length:9},()=>Array(10).fill(0));for(leti=0;i<9;i++){for(letj=0;j<9;j++){// Skip empty cellsif(mat[i][j]===0)continue;letval=mat[i][j];// Check duplicate in rowif(rows[i][val]===1)returnfalse;rows[i][val]=1;// Check duplicate in columnif(cols[j][val]===1)returnfalse;cols[j][val]=1;// Sub-matrix indexletidx=Math.floor(i/3)*3+Math.floor(j/3);// Check duplicate in sub-matrixif(subMat[idx][val]===1)returnfalse;subMat[idx][val]=1;}}returntrue;}// Driver codeletmat=[[5,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,9,8,0,0,0,0,6,0],[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]];console.log(isValid(mat)?"true":"false");
Output
true
[Expected Approach] 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<iostream>#include<vector>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={{5,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,9,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};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]={{5,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,9,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};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={{5,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,9,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};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=[[5,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,9,8,0,0,0,0,6,0],[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]]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={{5,3,0,0,7,0,0,0,0},{6,0,0,1,9,5,0,0,0},{0,9,8,0,0,0,0,6,0},{8,0,0,0,6,0,0,0,3},{4,0,0,8,0,3,0,0,1},{7,0,0,0,2,0,0,0,6},{0,6,0,0,0,0,2,8,0},{0,0,0,4,1,9,0,0,5},{0,0,0,0,8,0,0,7,9}};Console.WriteLine(IsValid(mat)?"true":"false");}}
JavaScript
functionisValid(mat){// Arrays to track seen numbers using bitmaskletrows=newArray(9).fill(0);letcols=newArray(9).fill(0);letsubMat=newArray(9).fill(0);for(leti=0;i<9;i++){for(letj=0;j<9;j++){// Skip empty cellsif(mat[i][j]===0)continue;letval=mat[i][j];// Bit position for current valueletpos=1<<(val-1);// Check duplicate in rowif((rows[i]&pos)!==0)returnfalse;rows[i]|=pos;// Check duplicate in columnif((cols[j]&pos)!==0)returnfalse;cols[j]|=pos;// Sub-matrix indexletidx=Math.floor(i/3)*3+Math.floor(j/3);// Check duplicate in sub-matrixif((subMat[idx]&pos)!==0)returnfalse;subMat[idx]|=pos;}}returntrue;}// Driver codeletmat=[[5,3,0,0,7,0,0,0,0],[6,0,0,1,9,5,0,0,0],[0,9,8,0,0,0,0,6,0],[8,0,0,0,6,0,0,0,3],[4,0,0,8,0,3,0,0,1],[7,0,0,0,2,0,0,0,6],[0,6,0,0,0,0,2,8,0],[0,0,0,4,1,9,0,0,5],[0,0,0,0,8,0,0,7,9]];console.log(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.