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 }

 

posted @ 2015-10-18 03:50  树獭君  阅读(529)  评论(0编辑  收藏  举报