看剑指offer时,看到全排列算法,后面的扩展引申,说可以用此思路解决8皇后问题,我就改成了解决n皇后问题。
之前出现函数参数值传递还是引用传递问题,就是由于此代码出问题引发的思考。
代码如下:
public class QueenProblem {
/*
* 不同行的皇后不能在同一列,且任意两个皇后不能在同一对角线上
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
QueenProblem question = new QueenProblem();
int n = 4;
int count = question.counOfQueenProblem(n);
System.out.println(n + "皇后问题共有 "+ count + " 种解法。");
}
// 初始化皇后的位置
// 譬如queens[i] = j,表示第i行的皇后在第j列
//这种初始化保证了不同皇后不可能在同一行,而对于列值,只进行交换操作,保证了不同皇后不可能在同一列
public int counOfQueenProblem(int numberOfQueens) {
if (numberOfQueens < 4)
return 0;
else {
int[] queens = new int[numberOfQueens];
for (int i = 0; i < numberOfQueens; i++)
queens[i] = i;
return countsOfQueenPlace(queens, 0);
}
}
public int countsOfQueenPlace(int[] queens, int index) {
int count = 0;
if (index == queens.length - 1) {
boolean flag = true;
for (int i = 0; i < queens.length; i++) {
for (int j = 0; j < queens.length; j++) {
if (i != j) {
//判断是否有两个皇后在同一对角线上
if (i - j == queens[i] - queens[j]
|| j - i == queens[i] - queens[j]) {
flag = false;
break;
}
}
}
if (!flag)
break;
}
if (flag) {
printQueens(queens);
count++;
}
} else {
for (int i = index; i < queens.length; i++) {
swap(queens, index, i);
count += countsOfQueenPlace(queens, index + 1);
swap(queens, i, index);
}
}
return count;
}
void swap(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
void printQueens(int[] queens) {
for (int i = 0; i < queens.length; i++) {
for (int j = 0; j < queens[i]; j++) {
System.out.print("*");
}
System.out.println("Q");
}
System.out.println("========================");
}
}
下面是4皇后问题的输出结果:
*Q
***Q
Q
**Q
========================
**Q
Q
***Q
*Q
========================
4皇后问题共有 2 种解法。
只需要改变主函数中 n 的值,便可求出对应 n皇后问题 的解,篇幅有限,只展示下 4皇后问题的结果, 但是n值若是太大应该会出问题,毕竟是使用递归做的。