代码随想录算法训练营第30天|51.N皇后、37.解数独
一. 回溯相关算法题
51.N皇后
思路
- 回溯法查找每一层符合条件的皇后坐标
- 在每一层查找的过程中判断当前坐标点能否符合条件
- 横竖方向没有皇后
- 斜向没有皇后:45度,135度
class Solution {
List<List<String>> res = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] chessboard = new char[n][n];
for (char[] c : chessboard) {
Arrays.fill(c, '.');
}
backTrack(n, 0, chessboard);
return res;
}
public void backTrack(int n, int row, char[][] chessboard) {
if (row == n) {
res.add(Array2List(chessboard));
return;
}
for (int col = 0;col < n; ++col) {
if (isValid (row, col, n, chessboard)) {
chessboard[row][col] = 'Q';
backTrack(n, row+1, chessboard);
chessboard[row][col] = '.';
}
}
}
public List Array2List(char[][] chessboard) {
List<String> list = new ArrayList<>();
for (char[] c : chessboard) {
list.add(String.copyValueOf(c));
}
return list;
}
public boolean isValid(int row, int col, int n, char[][] chessboard) {
for (int i=0; i<row; ++i) {
if (chessboard[i][col] == 'Q') {
return false;
}
}
for (int i=row-1, j=col-1; i>=0 && j>=0; i--, j--) {
if (chessboard[i][j] == 'Q') {
return false;
}
}
for (int i=row-1, j=col+1; i>=0 && j<=n-1; i--, j++) {
if (chessboard[i][j] == 'Q') {
return false;
}
}
return true;
}
}
37.解数独
思路
- 要在一般回溯模板的基础上加两个for循环遍历行和列
- 通过行和列得到一个坐标然后判断这个坐标一次放置1-9是否存在正解
- 如果1-9都不满足返回false
- 1-9是否符合条件的判断:
- 行列方向是否存在重复
- 同一个3*3九宫格中是否存在重复
class Solution {
public void solveSudoku(char[][] board) {
backTracking(board);
}
public boolean backTracking(char[][] board){
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++){
if (board[i][j] != '.') continue;
for (char k = '1'; k <= '9'; k++) {
if (isValid(board,i,j, k)){
board[i][j] = k;
if (backTracking(board)) return true;
board[i][j] = '.';
}
}
return false;
}
}
return true;
}
public boolean isValid(char[][] board, int row, int col, char val){
for (char c : board[row]) {
if (c == val){
return false;
}
}
for (int i = 0; i < 9; i++) {
if (board[i][col] == val){
return false;
}
}
int startX = 3*(row/3);
int startY = 3*(col/3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[startX+i][startY+j] == val){
return false;
}
}
}
return true;
}
}