import java.util.*; public class EightQueens { // 方法一:暴力穷举 public List<int[]> eightQueens1(){ // 定义保存结果的List ArrayList<int[]> result = new ArrayList<>(); // 用一个int[8]数组保存一组解 int[] solution = new int[8]; // 遍历八皇后每种可以摆放的场景,判断是否符合题目限制 for (solution[0] = 0; solution[0] < 8; solution[0] ++){ for (solution[1] = 0; solution[1] < 8; solution[1] ++){ for (solution[2] = 0; solution[2] < 8; solution[2] ++){ for (solution[3] = 0; solution[3] < 8; solution[3] ++){ for (solution[4] = 0; solution[4] < 8; solution[4] ++){ for (solution[5] = 0; solution[5] < 8; solution[5] ++){ for (solution[6] = 0; solution[6] < 8; solution[6] ++){ for (solution[7] = 0; solution[7] < 8; solution[7] ++){ if (check(solution)) result.add(Arrays.copyOf(solution, 8)); } } } } } } } } return result; } // 定义一个判定当前摆放方式是否有效的方法 private boolean check(int[] a){ // 任意两个皇后进行比较 for (int i = 0; i < 7; i++){ for (int j = i + 1; j < 8; j++){ // 不能在同一列,并且行列索引差不能相等 if (a[i] == a[j] || Math.abs(a[i] - a[j]) == j - i) return false; } } return true; } // 方法二:回溯 HashSet<Integer> cols = new HashSet<>(); HashSet<Integer> diags1 = new HashSet<>(); HashSet<Integer> diags2 = new HashSet<>(); public List<int[]> eightQueens(){ // 定义保存结果的List ArrayList<int[]> result = new ArrayList<>(); // 用一个int[8]数组保存一组解 int[] solution = new int[8]; // 先对solution做初始填充,表示皇后还没有填充 Arrays.fill(solution, -1); // 定义回溯方法,递归调用 backtrack(result, solution, 0); return result; } // 实现回溯方法 private void backtrack(ArrayList<int[]> result, int[] solution, int row){ // 首先处理递归调用结束场景 if (row >= 8){ // 已经直接得到了所有行的填充结果,构建了一组解 result.add(Arrays.copyOf(solution, 8)); } else { // 对于当前行,考察可能的皇后位置,遍历每一列 for (int column = 0; column < 8; column ++){ // 1.如果已经和之前的皇后冲突,直接跳过,寻找下一位置 // 1.1 判断同一列 if (cols.contains(column)) continue; // 1.2 判断两条斜线 int diag1 = row - column; int diag2 = row + column; if (diags1.contains(diag1)) continue; if (diags2.contains(diag2)) continue; // 2. 如果不冲突,当前位置就放置皇后 solution[row] = column; cols.add(column); diags1.add(diag1); diags2.add(diag2); // 3. 递归调用,深度搜索下一行 backtrack(result, solution, row + 1); // 4. 回溯,将状态回滚,继续遍历当前行皇后可能的位置 solution[row] = -1; cols.remove(column); diags1.remove(diag1); diags2.remove(diag2); } } } public static void main(String[] args) { EightQueens eightQueens = new EightQueens(); List<int[]> result = eightQueens.eightQueens(); System.out.println("八皇后问题一共有" + result.size() + "种不同的摆法"); for (int[] solution: result){ printQueens(solution); System.out.println("================="); } } // 打印解的方法 public static void printQueens(int[] queens){ int n = queens.length; // 打印每一行 for (int i = 0; i < n; i++){ String[] line = new String[n]; Arrays.fill(line, "□"); line[queens[i]] = "Q"; for (String str: line) System.out.print(str + "\t"); System.out.println(); } } }