leetcode51. N皇后
题目描述
链接: leetcode51.
n皇后问题 研究的是如何将 n个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的n皇后问题 的解决方案。
每一种解法包含一个不同的n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。
示例1:
输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
示例2:
输入:n = 1
输出:[["Q"]]
提示:
- 1 <= n <= 9
- 皇后彼此不能相互攻击,也就是说:任何两个皇后都不能处于同一条横行、纵行或斜线上。
题解
经典回溯算法
public class NQueens51 {
List<List<String>> res = new LinkedList<>();
public List<List<String>> solveNQueens(int n) {
char[][] boards = new char[n][n]; // 定义nxn棋盘
for (int i = 0; i < n; ++i) { // 每一个格子都填充为.
Arrays.fill(boards[i], '.');
}
trackBack(boards, 0); // 从第一行开始往下遍历
return res;
}
// 路径:board 中小于 row 的那些行都已经成功放置了皇后
// 选择列表:第 row 行的所有列都是放置皇后的选择
// 结束条件:row 超过 board 的最后一行
private void trackBack(char[][] boards, int row) {
if (row >= boards.length) {
res.add(convertArrayToList(boards));
return;
}
for (int col = 0; col < boards.length; ++col) { // 对于当前行的所有列
if (!isValidSelect(boards, row, col)) {
continue;
}
boards[row][col] = 'Q';
trackBack(boards, row + 1);
boards[row][col] = '.';
}
}
private List<String> convertArrayToList(char[][] boards) {
List<String> ans = new ArrayList<>();
for (char[] rows : boards) {
ans.add(new String(rows));
}
return ans;
}
// 能否在row,col位置放置Q
private boolean isValidSelect(char[][] boards, int row, int col) {
// 列冲突
for (char[] board : boards) {
if (board[col] == 'Q') {
return false;
}
}
// 右上方
for (int i = row, j = col; i >= 0 && j < boards.length; --i, ++j) {
if (boards[i][j] == 'Q') {
return false;
}
}
// 左上方
for (int i = row, j = col; i >= 0 && j >= 0; --i, --j) {
if (boards[i][j] == 'Q') {
return false;
}
}
return true;
}
}
- golang解法
var res [][]string
func solveNQueens(n int) [][]string {
board := make([]string, n)
for i := 0; i < n; i++ {
board[i] = stringFill(n)
}
trackBack(board, 0)
return res
}
func stringFill(n int) string {
var ans string
for i := 0; i < n; i++ {
ans = ans + "."
}
return ans
}
func trackBack(board []string, index int) {
if len(board) <= index {
res = append(res, board)
return
}
for i := 0; i < len(board); i++ {
if !isValid(board, index, i) {
continue
}
temp := append([]string{}, board...)
temp[index] = replaceNth(temp[index], i)
trackBack(temp, index+1)
}
}
func replaceNth(str string, n int) string {
arr := make([]string, len(str))
for i := 0; i < len(str); i++ {
if i != n {
arr[i] = "."
} else {
arr[i] = "Q"
}
}
var ans string
for _, s := range arr {
ans = ans + s
}
return ans
}
func isValid(board []string, row int, col int) bool {
for _, b := range board {
if b[col] == 'Q' {
return false
}
}
for i, j := row, col; i >= 0 && j < len(board); i, j = i-1, j+1 {
if board[i][j] == 'Q' {
return false
}
}
for i, j := row, col; i >= 0 && j >= 0; i, j = i-1, j-1 {
if board[i][j] == 'Q' {
return false
}
}
return true
}