参考51. N 皇后。
题目
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n 皇后问题 研究的是如何将 n
个皇后放置在 n×n
的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n
,返回所有不同的 **n 皇后问题 的解决方案。每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。

输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
输入:n = 1
输出:[["Q"]]
提示:
1 <= n <= 9
解题思路
- 回溯:皇后必须每行每列都只有一个,每次递归搜索一行,枚举列,尝试放置皇后,可用回溯。
回溯
class Solution {
int n;
List<List<String>> ans = new ArrayList<>();
char[] c;
public List<List<String>> solveNQueens(int n) {
//根据坐标系关系可知当选则坐标(x,y)则其他坐标不能包含x,y且y2-x2!=y-x,y2+x2!=y+x
//每个皇后占据一行/一列 可固定行枚举列
this.n = n;
c = new char[n];
Arrays.fill(c,'.');
//枚举皇后在第一行的可能位置
for(int i = 0; i < n; i++) {
int[] res = new int[n];
res[0] = i;
dfs(res,1);
}
return ans;
}
//index表示当前数量 找下一个满足条件的坐标列cur[index]
void dfs(int[] cur,int index) {
//如果找到了n个满足题意结果+1
if(index == n) {
List<String> list = new ArrayList<String>();
for(int i = 0; i < n; i++) {
c[cur[i]] = 'Q';
list.add(new String(c));
c[cur[i]] = '.';
}
ans.add(list);
return;
}
//枚举列
for(int j = 0; j < n; j++) {
//判断是否有满足的列
boolean ok = true;
for(int i = 0; i < index; i++) {
if(!check(i,cur[i],index,j)) {
ok = false;
break;
}
}
if(ok) {
cur[index] = j;
dfs(cur,index+1);
cur[index] = 0;
}
}
}
boolean check(int i,int j,int x,int y) {
return !(j == y || j-i == y-x || j+i == y+x); //i == x可去掉 因为找新的一行肯定不等
}
}
复杂度分析
- 时间复杂度:
O(n!)
。 - 空间复杂度:
O(n)
。
网友评论