N-Queens 解答
Question
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
Given an integer n, return all distinct solutions to the n-queens puzzle.
Each solution contains a distinct board configuration of the n-queens' placement, where 'Q'
and '.'
both indicate a queen and an empty space respectively.
For example,
There exist two distinct solutions to the 4-queens puzzle:
[ [".Q..", // Solution 1 "...Q", "Q...", "..Q."], ["..Q.", // Solution 2 "Q...", "...Q", ".Q.."] ]
Solution
N-queens问题是NP问题。基本思想其实是用brute-force列举出所有可能然后检查。
这里我们可以用一维数组来表示棋盘。A[rowNum] = colNum代表(rowNum, colNum)处是queen。
用迭代的方法进行层层遍历。
到第x行时,说明前(x - 1)行的queen放置都合法。
那我们就遍历前(x - 1)行的结果,如果当前第x行放置的点:
1. 列的值与之前的重复 --> false
2. (行 + 列)或 (行 - 列)的值和之前的 (行 + 列)或(行 - 列)的值相同 --> false
注意对于这题,因为是用一维数组表示棋盘,所以我们不用恢复迭代时设置的queen的位置值。
(参考:CodeGanker, 小莹子)
1 public class Solution { 2 public List<List<String>> solveNQueens(int n) { 3 List<List<String>> result = new ArrayList<List<String>>(); 4 // Here, we use a 1-D array to represent queen positions 5 // queen[1] = 2 means that on (1, 2), there is a queen 6 int[] queen = new int[n]; 7 helper(n, 0, result, queen); 8 return result; 9 } 10 11 private void helper(int n, int rowNum, List<List<String>> result, int[] queen) { 12 if (rowNum == n) { 13 List<String> oneResult = new ArrayList<String>(); 14 // Current chess board is valid 15 for (int i = 0; i < n; i++) { 16 StringBuilder sb = new StringBuilder(n); 17 int tmp = n; 18 while (tmp > 0) { 19 sb.append("."); 20 tmp--; 21 } 22 int column = queen[i]; 23 sb.replace(column, column + 1, "Q"); 24 oneResult.add(sb.toString()); 25 } 26 result.add(oneResult); 27 return; 28 } 29 30 for (int i = 0; i < n; i++) { 31 queen[rowNum] = i; 32 if (check(rowNum, queen)) 33 helper(n, rowNum + 1, result, queen); 34 } 35 } 36 37 private boolean check(int rowNum, int[] queen) { 38 int colNum = queen[rowNum]; 39 for (int i = 0; i < rowNum; i++) { 40 if (queen[i] == colNum || (queen[i] + i == rowNum + colNum) || (queen[i] - i == colNum - rowNum)) 41 return false; 42 } 43 return true; 44 } 45 }