package app;
import java.util.*;
/**
* @Author lyr
* @create 2019/9/30 0:28
*/
public class Main {
public static void main(String[] args) {
System.out.println(new Solution().solveNQueens(8));
}
static
class Solution {
static class DefaultMap{
Map<Integer,Boolean> map = new HashMap<>();
public boolean get(Integer i)
{
return map.getOrDefault(i,false);
}
public void put(Integer i,Boolean v)
{
map.put(i,v);
}
public boolean contain(Integer i)
{
return map.containsKey(i);
}
}
DefaultMap col = new DefaultMap();
DefaultMap dia1 = new DefaultMap();
DefaultMap dia2 = new DefaultMap();
void backTrack(List ans,int index,int N,Stack<Integer> indexMap)
{
if(index == N)
{
ans.add(newBoard(N,indexMap));//
return;
}
for (int i=0;i<N;++i)//N个列,第 index 行,主对角线是相减为定值,副对角线是相互加为定值
{
if(!col.get(i) && !dia1.get(i+index) && !dia2.get(i-index)) {
indexMap.add(i);
col.put(i,true);
dia1.put(i+index,true);
dia2.put(i-index,true);
backTrack(ans,index+1,N,indexMap);
indexMap.pop();
col.put(i,false);
dia1.put(i+index,false);
dia2.put(i-index,false);
}
}
}
public List<List<String>> solveNQueens(int n) {
List<List<String>> ans = new LinkedList<>();
backTrack(ans,0,n,new Stack<Integer>());
return ans;
}
List<String> newBoard(int n,Stack<Integer> indexMap)
{
List<String> list = new ArrayList<>();
for(Integer pos: indexMap)
{
StringBuilder sb = new StringBuilder();
for(int i=0;i<n;++i)
{
sb.append(".");
}
sb.replace(pos,pos+1,"Q");
list.add(sb.toString());
}
return list;
}
}
}
这个代码是有优化的,比如可以用 数组代替 HashMap 效率会更高,但是HashMap 比较通用,不用考虑数组越界等等数学问题。
思路分析
首先,下一行放皇后的话,这个皇后不能和前面的那些皇后在一条直线上,
不能同列,不能同撇,也不能同捺
经过观察,同一撇的位置,x+y 是一个常数,同一捺的位置 x-y (或者 y-x) 是一个常数,所以可以开一个 boolean 数组去标记相关的 位置,这里为了方便,使用 Hashmap 来处理,所以拼不过那些开数组的代码