【LeetCode】 37. Sudoku lösen

1. Titel

Schreiben Sie ein Programm, um das Sudoku-Problem durch die ausgefüllten Felder zu lösen.
Eine Sudoku-Lösung muss die folgenden Regeln befolgen :

Die Zahlen 1-9 können nur einmal pro Zeile erscheinen.
Die Zahlen 1-9 können in jeder Spalte nur einmal vorkommen.
Die Zahlen 1-9 können nur einmal in jedem 3x3-Palast erscheinen, der durch eine dicke durchgezogene Linie getrennt ist.
Leere Zellen werden durch '.' Dargestellt.
Sudoku
Ein Sudoku. Die Antwort ist rot markiert.

Hinweis:

  • Die angegebene Sudoku-Sequenz enthält nur die Nummern 1-9 und das Zeichen '.'.
  • Sie können davon ausgehen, dass ein bestimmtes Sudoku nur eine einzige Lösung hat.
  • Ein gegebenes Sudoku ist immer im 9x9-Format.

Zwei, lösen

1. Rekursionsszenariosimulation

Version 1

Ideen:

Durchlaufen Sie jede leere Zelle zeilenweise, versuchen Sie, die Zahl x (Bereich: 1-9) in jede leere Zelle einzugeben, und prüfen Sie dann, ob die Zeile, die Spalte und das 3 * 3-Haus wiederholt werden. Wenn dies wiederholt wird, kehren Sie direkt zurück und kehren Sie zur vorherigen Zelle zurück. Füllen Sie dann x + 1 aus und versuchen Sie es erneut. Wenn alle Zahlen nach Abschluss des Durchlaufs qualifiziert sind, wird das mit Zahlen gefüllte zweidimensionale Array zurückgegeben.

Code:

class Solution {
    
    
    public void solveSudoku(char[][] board) {
    
    
        if(board == null || board.length == 0)  return;
        solve(board);
    }
    
    public boolean solve(char[][] board){
    
    
        for(int row = 0; row < board.length; row++){
    
    
            for(int col = 0; col < board[0].length; col++){
    
    
                if(board[row][col] == '.'){
    
    
                    for(char c = '1'; c <= '9'; c++){
    
    //trial. Try 1 through 9
                        if(isValid(board, row, col, c)){
    
    
                            board[row][col] = c; //Put c for this cell
                            if(solve(board))
                                return true; //If it's the solution return true
                            else
                                board[row][col] = '.'; //Otherwise go back
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    
    private boolean isValid(char[][] board, int row, int col, char c){
    
    
        for(int i = 0; i < 9; i++) {
    
    
            if(board[i][col] != '.' && board[i][col] == c) return false; //check row
            if(board[row][i] != '.' && board[row][i] == c) return false; //check column
            if(board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != '.' && 
board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) return false; //check 3*3 block
        }
        return true;
    }
}

Zeitkomplexität: O (9 9 ∗ 9) O (9 ^ {9 * 9})O ( 99 9 )
Raumkomplexität: O (9 ∗ 9) O (9 * 9)O ( 99 )

Version 2

Ideen:

Grundsätzlich das gleiche wie Version 1, außer dass jedes Raster von 1 bis 81 nummeriert ist. Berechnen Sie dann die Ränge anhand der Anzahl und überprüfen Sie dann die Nummern der Zeilen, Spalten und Paläste. Das Zurückverfolgen ist ungültig. Der Effekt wird bis zum letzten fortgesetzt.

Code:

class Solution {
    
    
    public void solveSudoku(char[][] board) {
    
    
        if (board==null || board.length<9)  return;
        solveSudokuHelper(0, board);
    }

    public boolean solveSudokuHelper(int index, char[][] board) {
    
    
        int row = index/9, col = index%9;
        if (index==81)  return true;
        else {
    
    
            if (board[row][col]!='.') return solveSudokuHelper(index+1, board);
            else {
    
    
                for (char c='1'; c<='9'; c++) {
    
    
                    if (isValid(board, row, col, c)) {
    
    
                        board[row][col] = c;
                        if (solveSudokuHelper(index+1, board))  return true;
                        else board[row][col] = '.';
                    }
                }
                return false;
            }
        }
    }

    public boolean isValid(char[][] board, int row, int col, char c) {
    
    
        for (int i=0; i<9; i++) {
    
    
            if (board[row][i]!='.' && board[row][i]==c)  return false;
            if (board[i][col]!='.' && board[i][col]==c)  return false;
            if (board[row/3*3+i/3][col/3*3+i%3]!='.' && board[row/3*3+i/3][col/3*3+i%3]==c)  return false;
        }
        return true;
    }
}

Zeitkomplexität: O (9 9 ∗ 9) O (9 ^ {9 * 9})O ( 99 9 )
Raumkomplexität: O (9 ∗ 9) O (9 * 9)O ( 99 )

2. Bitbetrieb

Idee: Ich verstehe es vorerst nicht ganz, ein bisschen.
Code: leicht
zeitliche Komplexität: O (?) O (?)O ( ? )
Raumkomplexität: O (?) O (?)Die ( ? )

Drei, Referenz

1 、Geradlinige Java-Lösung mit Backtracking
2 、Zwei sehr einfache und übersichtliche Java-DFS / Backtracking-Lösungen
3 、Weniger als 30 Zeilen saubere Java-Lösung mit DFS
4 、解数 独

Ich denke du magst

Origin blog.csdn.net/HeavenDan/article/details/108585418
Empfohlen
Rangfolge