n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
[原题链接]leetcode-cn.com/problems/n-…
思路: 打算采用回溯来做,因为在回溯的典型题目是8皇后,所以这里也采用回溯来做。 假设a[i][j]代表棋盘的一个点位,假设占据其中一点,那么有如下几个公式可以推到
- a[i][0-n] 不可被其他皇后占用
- a[0-n][j] 不可被其他皇后占用
- 任意一点b[s][m] 当s+m = i+j,时,这个点位在a皇后的线上
- 任意一点b[s][m] 当s-m = i-j,时,这个点位在a皇后的线上
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> allList = new ArrayList();
// 层数
int i=0;
// 不能选的i
Set<Integer> seti = new HashSet();
// 不能选的j
Set<Integer> setj = new HashSet();
// 不能选的和
Set<Integer> setSum = new HashSet();
// 不能选的差
Set<Integer> setCum = new HashSet();
Map<Integer,String> k = new HashMap();
String result = "";
helper(allList,n,i,seti,setj,setSum,setCum,k);
return allList;
}
/***
**/
public void helper(List<List<String>> allList,int n,int i,
Set<Integer> seti,Set<Integer> setj,Set<Integer> setSum, Set<Integer> setCum,Map<Integer,String> k){
if(i == n){
// 平装返回的数据
List<String> templist = new ArrayList();
for(Integer key:k.keySet()){
if(key != n){
String v = k.get(key);
while(v.length() < n){
v = v+".";
}
templist.add(v);
}
}
k = new HashMap();
allList.add(templist);
}
k.put(i,"");
// 每一列都遍历
for(int r=0;r < n;r++){
if(check(i,r,seti,setj,setSum,setCum)){
String row = k.get(i);
k.put(i,row + "Q");
// 禁止 i 行
seti.add(i);
// 禁止 j 行
setj.add(r);
// 禁止斜线
setSum.add(i-r);
setCum.add(r+i);
helper(allList,n,i+1,seti,setj,setSum,setCum,k);
// 还原 i 行
seti.remove(i);
// 还原 j 行
setj.remove(r);
setSum.remove(i-r);
setCum.remove(r+i);
if(k.containsKey(i)){
k.put(i,row + ".");
}else{
k.put(i,"");
}
}else{
String row = k.get(i) + ".";
k.put(i,row);
continue;
}
}
k.putIfAbsent(i,"");
}
// 校验i,j 是否可以容下一个皇后
public boolean check(int i,int j,
Set<Integer> seti,Set<Integer> setj,Set<Integer> setSum,Set<Integer> setCum){
if(seti.contains(i)){
return false;
}
if(setj.contains(j)){
return false;
}
if(setSum.contains(i-j)){
return false;
}
if(setCum.contains(i+j)){
return false;
}
return true;
}
}
能过,但是时间和效率不够好,在评论区有很多优秀的方案,可以一起去看。