Leecode no.51 N 皇后

package leecode;

import java.util.*;

/**
* 51. N 皇后
*
* n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
* (皇后可以攻击同一行 同一列 左上 左下 右上 右下)
*
* 给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
*
* 每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
*
*
* @author Tang
* @date 2021/12/9
*/
public class SolveNQueens {

List<List<String>> result = new ArrayList<>();

char[][] chessboard;

public List<List<String>> solveNQueens(int n) {

//准备一个n*n的棋盘
//初始化全都是.
chessboard = new char[n][n];
for(int i = 0; i < chessboard.length; i++) {
Arrays.fill(chessboard[i], '.');
}

track(0);
return result;

}

private void track(int rowIndex) {
//结束条件 所有皇后都已经选完
if(rowIndex == chessboard.length) {
List<String> chooseList = new ArrayList<>();
for (char[] chars : chessboard) {
StringBuilder s = new StringBuilder();
for (char c : chars) {
s.append(c);
}
chooseList.add(s.toString());
}
result.add(chooseList);
return;
}

for(int i = 0; i < chessboard[rowIndex].length; i++) {
//递归前做出选择 选出皇后落在该行中的位置
if(!check(rowIndex, i)) {
continue;
}
chessboard[rowIndex][i] = 'Q';

//执行递归 去玩下一行
track(rowIndex + 1);

//递归后撤销选择
chessboard[rowIndex][i] = '.';
}

}

/**
* 判断某个点能否放皇后
* 也就是说该点的行,列,左上,右上是否唯一
*
* @param rowIndex 当前元素是第几行
* @param columnIndex 当前元素是第几列
* @return
*/
private boolean check(int rowIndex, int columnIndex) {
//行不需要判断 天然唯一

//列是否唯一
for(int i = 0; i < chessboard.length; i++) {
if(chessboard[i][columnIndex] == 'Q') {
return false;
}
}

//左上
int i = rowIndex-1;
int j = columnIndex-1;
while(i >= 0 && j >= 0) {
if(chessboard[i][j] == 'Q') {
return false;
}
i--;
j--;
}

//右上
i = rowIndex-1;
j = columnIndex+1;
while(i >= 0 && j < chessboard.length) {
if(chessboard[i][j] == 'Q') {
return false;
}
i--;
j++;
}
return true;
}




public static void main(String[] args) {

}


}
posted @ 2021-12-09 13:56  六小扛把子  阅读(23)  评论(0编辑  收藏  举报