N皇后问题 发表于 2019-07-08 | 分类于 代码练习 | 阅读次数: 题目描述 如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击(皇后攻击范围为横、竖以及对角线),输出所有可能的放置情况,皇后以Q表示。 示例输入n为4时,输出: 1234567891011[ [".Q..", // 解法 1 "...Q", "Q...", "..Q."],["..Q.", // 解法 2 "Q...", "...Q", ".Q.."]] 解答123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263public class NQueens { public static List<List<String>> solveNQueens(int n) { boolean[] col = new boolean[n]; boolean[] left = new boolean[2*n];//2n长度防止越界 boolean[] right = new boolean[2*n]; List<String> solution = new ArrayList<>(); List<List<String>> result = new ArrayList<>(); dfs(0, col, left, right, solution, result); return result; } /** * * @param row 标记当前行数 * @param column 标记当前行不可用的列,true为被占用 * @param cl 标记当前行不可用的左对角格(每一元素代表一条约束公式,数组下标由行号列号共同决定) * @param cr 标记标记当前行不可用的右对角格 * @param solution 一种可行答案 * @param result 所有答案集 */ public static void dfs(int row, boolean[] column, boolean[] cl, boolean[] cr, List<String> solution, List<List<String>> result){ if(row >= column.length){ List<String> copyArray = new ArrayList<>(solution); result.add(copyArray);//将一种可行情况放入结果数组中 }else{ for(int i = 0; i < column.length; i++){ int l = 2*column.length - i - row -1;//左斜约束 int r = i - row +column.length;//右斜约束 if(!column[i] && !cl[l] && !cr[r]){ char[] pointStr = new char[column.length]; Arrays.fill(pointStr, '.');//填充"." pointStr[i] = 'Q';//一旦放入Q该层遍历完成 String rowStr = new String(pointStr); solution.add(rowStr); /** * 更新标记不可用的数组 */ column[i] = true;cl[l] = true;cr[r] = true; dfs(row+1, column, cl, cr, solution, result);//递归进入下一行 /** * 用于回溯时清除标记数组 */ solution.remove(rowStr); column[i] = false;cl[l] = false;cr[r] = false; } } } } public static void main(String[] args) { List<List<String>> result = NQueens.solveNQueens(4); for (List<String> one : result) { for (String row : one) { System.out.println(row); } System.out.println(); } }}