LeetCode 题解(109): Sudoku Solver

题目:

Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.


A sudoku puzzle...


...and its solution numbers marked in red.

题解:

Back Tracing + Hash Table。

C++版:

class Solution {
public:
	void solveSudoku(vector<vector<char>>& board) {
		unordered_map<char, vector<bool>> row;
		unordered_map<char, vector<bool>> col;
		unordered_map<char, vector<bool>> cell;
		vector<pair<int, int>> pos;
		for (char i = '1'; i <= '9'; i++) {
			row.insert(pair<char, vector<bool>>(i, vector<bool>(9, false)));
			col.insert(pair<char, vector<bool>>(i, vector<bool>(9, false)));
			cell.insert(pair<char, vector<bool>>(i, vector<bool>(9, false)));
		}
		for (int i = 0; i < board.size(); i++) {
			for (int j = 0; j < board[0].size(); j++) {
				if (board[i][j] != '.') {
					row[board[i][j]][i] = true;
					col[board[i][j]][j] = true;
					cell[board[i][j]][(i / 3) * 3 + (j / 3)] = true;
				}
				else {
					pos.push_back(pair<int, int>(i, j));
				}
			}
		}

		int i = pos[0].first;
		int j = pos[0].second;

		for (char k = '1'; k <= '9'; k++) {
			if (!row[k][i] && !col[k][j] && !cell[k][(i / 3) * 3 + (j / 3)]) {
				board[i][j] = k;
				row[k][i] = true;
				col[k][j] = true;
				cell[k][(i / 3) * 3 + (j / 3)] = true;
				bool result = solver(board, row, col, cell, pos, 1);
				if (result)
					return;
				else {
					row[k][i] = false;
					col[k][j] = false;
					cell[k][(i / 3) * 3 + (j / 3)] = false;
				}
			}
		}
		return;
	}

	bool solver(vector<vector<char>>& board, unordered_map<char, vector<bool>>& row, unordered_map<char, vector<bool>>& col, unordered_map<char, vector<bool>>& cell, vector<pair<int, int>>& pos, int current) {
		if (pos.size() == current)
			return true;
		int i = pos[current].first;
		int j = pos[current].second;
		for (int k = '1'; k <= '9'; k++) {
			if (!row[k][i] && !col[k][j] && !cell[k][(i / 3) * 3 + (j / 3)]) {
				board[i][j] = k;
				row[k][i] = true;
				col[k][j] = true;
				cell[k][(i / 3) * 3 + (j / 3)] = true;
				bool result = solver(board, row, col, cell, pos, current+1);
				if (result)
					return true;
				else {
					row[k][i] = false;
					col[k][j] = false;
					cell[k][(i / 3) * 3 + (j / 3)] = false;
				}
			}
		}
		return false;
	}
};

Java版:

class Pos {
    int i;
    int j;
    Pos(int x, int y) {
        i = x;
        j = y;
    }
}

public class Solution {
    public void solveSudoku(char[][] board) {
        Map<Character, boolean[]> row = new HashMap<>();
        Map<Character, boolean[]> col = new HashMap<>();
        Map<Character, boolean[]> cell = new HashMap<>();
        List<Pos> pos = new ArrayList<>();
        for(char k = '1'; k <= '9'; k++) {
            row.put(k, new boolean[9]);
            col.put(k, new boolean[9]);
            cell.put(k, new boolean[9]);
        }
        for(int i = 0; i < board.length; i++) {
            for(int j = 0; j < board[0].length; j++) {
                if(board[i][j] != '.') {
                    row.get(board[i][j])[i] = true;
                    col.get(board[i][j])[j] = true;
                    cell.get(board[i][j])[i / 3 * 3 + j / 3] = true;
                } else {
                    pos.add(new Pos(i, j));
                }
            }
        }
        
        int i = pos.get(0).i;
        int j = pos.get(0).j;
        
        for(char k = '1'; k <= '9'; k++) {
            if(!row.get(k)[i] && !col.get(k)[j] && !cell.get(k)[i / 3 * 3 + j / 3]) {
                board[i][j] = k;
                row.get(k)[i] = true;
                col.get(k)[j] = true;
                cell.get(k)[i / 3 * 3 + j / 3] = true;
                boolean result = solver(board, row, col, cell, pos, 1);
                if(result)
                    return;
                else {
                    row.get(k)[i] = false;
                    col.get(k)[j] = false;
                    cell.get(k)[i / 3 * 3 + j / 3] = false;
                }
            }
        }
        
        return;
    }
    
    public boolean solver(char[][] board, Map<Character, boolean[]> row, Map<Character, boolean[]> col, Map<Character, boolean[]> cell, List<Pos> pos, int current) {
        if(current == pos.size())
            return true;
        int i = pos.get(current).i;
        int j = pos.get(current).j;
        for(char k = '1'; k <= '9'; k++) {
            if(!row.get(k)[i] && !col.get(k)[j] && !cell.get(k)[i / 3 * 3 + j / 3]) {
                board[i][j] = k;
                row.get(k)[i] = true;
                col.get(k)[j] = true;
                cell.get(k)[i / 3 * 3 + j / 3] = true;
                boolean result = solver(board, row, col, cell, pos, current + 1);
                if(result)
                    return true;
                else {
                    row.get(k)[i] = false;
                    col.get(k)[j] = false;
                    cell.get(k)[i / 3 * 3 + j / 3] = false;
                }
            }
        }
        return false;
    }
}

Python版:

class Solution:
    # @param {character[][]} board
    # @return {void} Do not return anything, modify board in-place instead.
    def solveSudoku(self, board):
        row, col, cell, pos = {}, {}, {}, []
        for i in "123456789":
            row[i] = [False] * 9
            col[i] = [False] * 9
            cell[i] = [False] * 9
        
        for i in range(0, 9):
            for j in range(0, 9):
                if board[i][j] != '.':
                    row[board[i][j]][i] = True
                    col[board[i][j]][j] = True
                    cell[board[i][j]][i / 3 * 3 + j / 3] = True
                else:
                    pos.append((i, j))
        
        i = pos[0][0]
        j = pos[0][1]
        
        for k in "123456789":
            if not row[k][i] and not col[k][j] and not cell[k][i / 3 * 3 + j / 3]:
                board[i][j] = k
                row[board[i][j]][i] = True
                col[board[i][j]][j] = True
                cell[board[i][j]][i / 3 * 3 + j / 3] = True
                result = self.solver(board, row, col, cell, pos, 1)
                if result:
                    return
                else:
                    row[board[i][j]][i] = False
                    col[board[i][j]][j] = False
                    cell[board[i][j]][i / 3 * 3 + j / 3] = False
        
        return
    
    def solver(self, board, row, col, cell, pos, current):
        if current == len(pos):
            return True
        i = pos[current][0]
        j = pos[current][1]
        for k in "123456789":
            if not row[k][i] and not col[k][j] and not cell[k][i / 3 * 3 + j / 3]:
                board[i][j] = k
                row[board[i][j]][i] = True
                col[board[i][j]][j] = True
                cell[board[i][j]][i / 3 * 3 + j / 3] = True
                result = self.solver(board, row, col, cell, pos, current + 1)
                if result:
                    return True
                else:
                    row[board[i][j]][i] = False
                    col[board[i][j]][j] = False
                    cell[board[i][j]][i / 3 * 3 + j / 3] = False
        
        return False
                


你可能感兴趣的:(Algorithm,LeetCode,面试题)