1. ルール
8 クイーン問題は古典的なバックトラッキング アルゴリズムの問題で、互いに攻撃できないように (つまり、同じ行、列、または対角線上に配置できない)8×8
チェス盤上に配置されたクイーンを見つけることを目的としています。8
2. コードの実装
public class EightQueens {
// 棋盘行列数为 8
private static int SIZE = 8;
// 用一维数组记录八皇后的摆放方案
// q[i] 中的 i 表示第几个皇后
// q[i] 表示该皇后放在哪一列
private static int[] q = {
-1, -1, -1, -1, -1, -1, -1, -1};
public static void main(String[] args) {
placeQueen(0);
}
// 放置皇后,row 表示第几个皇后
public static void placeQueen(int row) {
// 如果 row = 8,说明所有皇后已经摆放完成
// 直接打印摆放后的棋局
if (row == SIZE) {
printQueen();
} else {
for (int col = 0; col < SIZE; col++) {
// 判断皇后是否能放在该格
// 可以则进行下一个皇后的摆放
if (isSafe(row, col)) {
q[row] = col;
placeQueen(row + 1);
}
}
}
}
// 判断该格是否安全
public static boolean isSafe(int row, int col) {
for (int i = 0; i < row; i++) {
// 是否与已摆放的皇后位于同一列、位于左上到右下的对角线、位于右上到左下的对角线
if (q[i] == col || q[i] - i == col - row || q[i] + i == col + row) {
return false;
}
}
return true;
}
// 打印摆放后的棋局,Q表示皇后
public static void printQueen() {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (q[i] == j) {
System.out.printf("Q ");
} else {
System.out.printf(". ");
}
}
System.out.println();
}
System.out.println();
}
}
-
時間の複雑さ
placeQueen()
メソッドは、クイーンを再帰的に配置するための主なメソッドです。各再帰レベルでは、ボードの各列を走査する必要があるため、時間計算量は になりますO(N)
。ここで、N
はボードのサイズです。N
配置するクイーンの合計があるため、合計の時間計算量は ですO(N^N)
。isSafe()
この方法は、現在のグリッドが安全かどうか、つまりすでに配置されているクイーンと競合していないかどうかを判断するために使用されます。各再帰レベルで配置されたクイーンを走査する必要があるため、時間計算量は ですO(N)
。合計のクイーンがあるためN
、合計の時間計算量は になりますO(N^2)
。printQueen()
このメソッドは配置後にチェスのゲームを出力するために使用され、チェス盤全体を走査する必要があり、時間計算量は ですO(N^2)
。
要約すると、アルゴリズムの合計時間計算量は です
O(N^N)
。 -
空間の複雑さ
- このアルゴリズムは 1 次元配列を使用して
q
8 つのクイーンの配置スキームを記録し、その長さは であるためN
、空間複雑さは ですO(N)
。
要約すると、アルゴリズムの空間複雑さの合計は です
O(N)
。 - このアルゴリズムは 1 次元配列を使用して
3. 走行結果
. . . . . . . Q
. . . Q . . . .
Q . . . . . . .
. . Q . . . . .
. . . . . Q . .
. Q . . . . . .
. . . . . . Q .
. . . . Q . . .