Solve the Sudoku | Practice | GeeksforGeeks

Given an incomplete Sudoku configuration in terms of a 9 x 9  2-D square matrix (grid[][]), the task to find a solved Sudoku. For simplicity, you may assume that there will be only one unique solution.

Sample Sudoku for you to get the logic for its solution:



Example 1:
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


Your Task:
You need to complete the two functions:
SolveSudoku(): Takes a grid as its argument and returns true if a solution is possible and false if it is not.
printGrid(): Takes a grid as its argument and prints the 81 numbers of the solved Sudoku in a single line with space separation.

Expected Time Complexity: O(9N*N).
Expected Auxiliary Space: O(N*N).

Constraints:
0 ≤ grid[i][j] ≤ 9
0
milindprajapatmst19in 12 hours
Total Time Taken: 0.04/1.1
 
class Solution {
public:
    bool check(int grid[N][N], int x, int y, int digit) {
        for (int k = 0; k < N; k++) {
            if (grid[x][k] == digit || grid[k][y] == digit)
                return false;
        }
        x /= 3; y /= 3;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (grid[3 * x + i][3 * y + j] == digit)
                    return false;
            }
        }
        return true;
    }
    bool SolveSudoku(int grid[N][N], int x = 0, int y = 0) { 
        if (x == N)
            return true;
        if (y == N)
            return SolveSudoku(grid, x + 1, 0);
        if (grid[x][y] == 0) {
           for (int k = 1; k <= N; k++) {
               if (check(grid, x, y, k)) {
                   grid[x][y] = k;
                   if (SolveSudoku(grid, x, y + 1))
                       return true;
                   grid[x][y] = 0;
               }
           }
           return false;
        }
        else
            return SolveSudoku(grid, x, y + 1);
    }
    void printGrid(int grid[N][N]) {
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)
                cout << grid[i][j] << " ";
    }
};
+1
dev1712 weeks ago
C++ SIMPLE backtracking 
 bool getCell(int grid[N][N],int &i,int &j){
        for(i=0;i<9;i++){
            for(j=0;j<9;j++){
                if(grid[i][j]==0)
                return true;
            }
        }
        return false;
    }
    bool valid(int grid[N][N],int row,int col,int num){
        for(int i=0;i<9;i++){
            if(grid[row][i]==num)
            return false;
            
           if(grid[i][col]==num)
            return false;
        }
        
        int rf=(row/3)*3;
        int cf=(col/3)*3;
        
        for(int i=rf;i<rf+3;i++){
            for(int j=cf;j<cf+3;j++){
                if(grid[i][j]==num)
                return false;
            }
        }
        return true;
        
    }
    bool SolveSudoku(int grid[N][N])  
    { 
        // Your code here
        int row,col;
        if(!getCell(grid,row,col)){
            return true;
        }
        for(int i=1;i<=9;i++){
            if(valid(grid,row,col,i)){
                grid[row][col]=i;
                if(SolveSudoku(grid))
                return true;
                grid[row][col]=0;
            }
        }
        return false;
    }
    
0
sunboykenneth3 weeks ago
struct IndexSt {
    int x;
    int y;
    
    IndexSt(int x, int y) {
        this->x = x;
        this->y = y;
    }
};

class Solution 
{
    private:
    struct IndexSt getBlockOrigin(int curX, int curY) {
        int xBlock = curX / 3;
        int yBlock = curY / 3;
        return IndexSt(xBlock * 3, yBlock * 3);
    }
    
    struct IndexSt moveToNextPosition (int curX, int curY) {
        curY = curY + 1;
        if (curY == N) {
            curY = 0;
            curX = curX + 1;
        }
        return IndexSt(curX, curY);
    }
    
    bool solveSudoKuImpl(int grid[N][N], int curX, int curY) {
        if (curX == N) {
            return true;
        }
        
        struct IndexSt blockOrigin = getBlockOrigin(curX, curY);
        vector<bool> availableNums = vector<bool>(N + 1, true);
        
        // Check row
        for (int i = 0; i < N; i++) {
            if (i != curX) {
                availableNums[grid[curY][i]] = false;
            }
        }
        
        // Check column
        for (int i = 0; i < N; i++) {
            if (i != curY) {
                availableNums[grid[i][curX]] = false;
            }
        }
        
        // Check square block
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                int x = blockOrigin.x + i;
                int y = blockOrigin.y + j;
                if (x != curX && y != curY) {
                    availableNums[grid[y][x]] = false;
                }
            }
        }
        
        struct IndexSt nextPosition =  moveToNextPosition(curX, curY);
        
        if (grid[curY][curX] > 0) {
            if (!availableNums[grid[curY][curX]]) {
                return false;
            }
            
            return solveSudoKuImpl(grid, nextPosition.x, nextPosition.y);
        } 
        
        // Try all available nums
        for (int i = 1; i <= N; i++) {
            if (!availableNums[i]) {
                continue;
            }
            
            grid[curY][curX] = i;
            if (solveSudoKuImpl(grid, nextPosition.x, nextPosition.y)) {
                return true;
            }
            grid[curY][curX] = 0;
        }
        
        return false;
    }
    
    
    public:
    //Function to find a solved Sudoku. 
    bool SolveSudoku(int grid[N][N])  
    { 
        return solveSudoKuImpl(grid, 0, 0);
    }
    
    //Function to print grids of the Sudoku.
    void printGrid (int grid[N][N]) 
    {
        if (!SolveSudoku(grid)) {
            return;
        }
        
        for (int y = 0; y < N; y++) {
            for (int x = 0; x < N; x++) {
                cout << grid[y][x] << " ";
            }
        }
    }
};
0
harrypotter04 weeks ago
def check(grid, ch, r, c):
   
   ## horizontal
   for i in range(9):
       
       
       if grid[r][i] == ch:
           return False
           
       if grid[i][c] == ch:
           return False
           
       if grid[int(3*(r//3)+i//3)][int(3*(c//3)+i%3)] == ch:
           return False
           
   return True
   

def solve(grid):
   for i in range(9):
       for j in range(9):
           if grid[i][j] ==0:
               for ch in range(1,10):
                   if check(grid, ch, i, j):
                       grid[i][j] = ch
                       # solve(grid)
                       if solve(grid):
                           return True
                       else:                          
                           grid[i][j] = 0
               return False    
   
   return True
class Solution:
   def SolveSudoku(self,grid):
       return solve(grid)
   def printGrid(self,arr):
       for i in range(len(arr)):
           for j in range(len(arr[0])):
               print(arr[i][j], end = " ")

0
adityagagtiwari
This comment was deleted.
0
adityagagtiwari1 month ago
I dont know why you call this a hard problem.
It requires least amount of effort comparing with other backtracking problems
0
vinayakamikkal1 month ago
    def SolveSudoku(self,grid):       placement = set()       remaining = len(grid)*len(grid[0])       for i in range(len(grid)):           for j in range(len(grid[i])):               if grid[i][j]!=0:                   c1 = "{}r-{}".format(i,grid[i][j])                   c2 = "{}c-{}".format(j,grid[i][j])                   c3 = "{}-{}-{}".format(i//3,j//3,grid[i][j])                   placement.add(c1)                   placement.add(c2)                   placement.add(c3)                   remaining-=1                     def solve(grid,presence,remaining):           if remaining==0:               return grid                                     for i in range(len(grid)):               for j in range(len(grid[0])):                   if grid[i][j]==0:                       for n in range(1,10):                           c1 = "{}r-{}".format(i,n)                           c2 = "{}c-{}".format(j,n)                           c3 = "{}-{}-{}".format(i//3,j//3,n)                                                      if c1 not in presence and c2 not in presence and c3 not in presence:                               presence.add(c1)                               presence.add(c2)                               presence.add(c3)                               grid[i][j] = n                                                              temp = solve(grid,presence,remaining-1)                               if temp:                                   return temp                                                               presence.remove(c1)                               presence.remove(c2)                               presence.remove(c3)                                                         grid[i][j] = 0                      return None                                         ans = solve(grid,placement,remaining)       if ans:           return True              else:           return False
Can anyone tell the reason for timeout?
0
kuldeepy104591 month ago
bool isempty(int grid[N][N],int &row ,int &col){         for(int i=0;i<N;i++){             for(int j=0;j<N;j++){                 if(grid[i][j]==0){                     row=i;                     col=j;                     return true;                 }             }         }         return false;   }   bool rowvalid(int grid[N][N],int row,int col,int number ){       for(int i=0;i<N;i++){           if(grid[row][i]==number){               return false;           }       }       return true;   }   bool colvalid(int grid[N][N],int row,int col,int number ){       for(int i=0;i<N;i++){           if(grid[i][col]==number){               return false;           }       }       return true;   }   bool innergrid(int grid[N][N],int row,int col,int number){       int rowfactor= row-row%3;       int colfactor= col-col%3;       for(int i=0;i<3;i++){           for(int j=0;j<3;j++){               if(grid[i+rowfactor][j+colfactor]==number){                   return false;           }           }       }       return true;   }   bool issafe(int grid[N][N],int row ,int col ,int number){         if(rowvalid(grid,row,col,number)&&colvalid(grid,row,col,number)&&innergrid(grid,row,col,number)){             return true;         }         return false;   }      bool SolveSudoku(int grid[N][N])     {        // Your code here       int row,col;       if(!isempty(grid,row,col)){           return true;       }       for(int i=1;i<=N;i++){            if(issafe(grid,row,col ,i)){                grid[row][col]=i;                if(SolveSudoku(grid)){                    return true;                }                grid[row][col]=0;            }       }       return false;   }      //Function to print grids of the Sudoku.   void printGrid (int grid[N][N])    {       // Your code here        for(int i=0;i<N;i++){           for(int j=0;j<N;j++){               cout<<grid[i][j]<<" ";           }       }   }
0
vinamrajha1 month ago
bool issafe(int row, int col, int i, int grid[N][N]){
       for(int k =0; k<N; ++k) if(grid[row][k]==i || grid[k][col]==i) return false;
       int rs = row - (row%3), cs = col - (col%3);
       for(int k =0; k<3; ++k){
           for(int l =0; l<3; ++l) if(grid[rs+k][cs+l]==i)return false;
       }
       return true;
   }
   bool SolveSudoku(int grid[N][N])  
   { 
       // Your code here
       int col =-1, row =-1;
       bool flag = false;
       for(int i =0; i<N; ++i){
           for(int j =0; j<N; ++j){
               if(grid[i][j]==0){
                   row = i;
                   col =j;
                   flag = true;
                   break;
               }
           }
           if(flag) break;
       }
       if(!flag)return true;
       for(int i =1; i<=N; ++i){
           if(issafe(row, col, i, grid)){
               grid[row][col] = i;
               if(SolveSudoku(grid)) return true;
               grid[row][col] =0;
           }
       }
       return false;
   }
   
   //Function to print grids of the Sudoku.
   void printGrid (int grid[N][N]) 
   {
       // Your code here
       for(int i =0; i<N; ++i){
           for(int j =0; j<N; ++j) cout << grid[i][j] << " ";
       }
   }
0
shivamsoni51 month ago
Did anyone try the algorithm with the following input?
 
For Input:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 8 5 0 0 1 0 2 0 0 0 0 0 0 0 5 0 7 0 0 0 0 0 4 0 0 0 1 0 0 0 9 0 0 0 0 0 0 0 5 0 0 0 0 0 0 7 3 0 0 2 0 1 0 0 0 0 0 0 0 0 4 0 0 0 9
 
If not, then try to run this with custom test input, you will get surprise!
And, given input has a valid solution for sure, for example
 
Your Output:
1 2 3 4 5 6 7 9 8 2 1 6 7 9 3 4 8 5 3 4 1 6 2 9 8 5 7 4 3 8 5 6 7 9 1 2 7 5 4 9 3 8 1 2 6 8 9 5 3 7 2 6 4 1 5 6 9 1 8 4 2 7 3 9 7 2 8 1 5 3 6 4 6 8 7 2 4 1 5 3 9
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.