题目
输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。
分析
问:用什么方法?
答:递归
问:如何判断格子在同一对角线?
答:同一正对角线的行数-列数相等,同一负对角线的行数+列数相等
问:如何用一维数组记录皇后位置?
答:下标记录行号,值记录列号。
题解
package com.company.test5;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test5 {
static int n=4;
static List<List<String>> list=new ArrayList<>();
public static void main(String[] args) {
int[] record=new int[n+1];
// record[1]=2;
// System.out.println(check(record, 2, 1));
board(record,1);
// for (String[] arr : list) {
// System.out.println(Arrays.toString(arr));
// }
System.out.println(list);
return;
}
public static void board(int[] record,int r){
if(r==n+1){
// System.out.println(Arrays.toString(record));
// 将record[2,4,1,3]构造成[".Q..","...Q","Q...","..Q."]这种形式
// ①将2构造成".Q.."
List<String> arr=new ArrayList<>();
for (int i = 0; i < n; i++) {
String s=replace(record[i+1]);
arr.add(s);
}
// 存入list
list.add(arr);
return;
}
for (int i = 1; i <n+1 ; i++) {
// 检查r行,i列可不可以放棋子?
// i列的前r-1行是否有其它棋子也在c列?(record[1,2,3,4]!=c)
// 该格子的对角线是否有其它棋子?
// (r,c)(i,record[i])在同一正对角线,r-c=i-record[i]
// (r,c)(m,n)在同一负对角线,r+c=m+n
if(check(record,r,i)){
record[r]=i;
board(record,r+1);
}
}
}
private static String replace(int m) {
// n=2
// String s=".Q..";
// Q前面有n-1个点,Q后面有4-n个点
StringBuilder b=new StringBuilder();
for (int i = 0; i < m - 1; i++) {
b.append(".");
}
b.append("Q");
for (int i = 0; i < n - m; i++) {
b.append(".");
}
return b.toString();
}
private static boolean check(int[] record, int r, int c) {
for (int i = 1; i < r; i++) {
if(record[i]==c){
return false;
}
if(i-record[i]==r-c){
return false;
}
if(i+record[i]==r+c){
return false;
}
}
return true;
}
//
}