1. 程式人生 > >[leetcode]51. N-QueensN皇后

[leetcode]51. N-QueensN皇后

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.

Example:

Input: 4
Output: [
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.

題目

NxN棋盤擺N個棋子,要求不能同行、同列、同對角線、同反對角線,返回所有擺法。

 

思路

DFS: C[i] 表示第i行皇后所在的列編號,即在位置 (i, C[i])上放了一個皇后,這樣用一個一維陣列,就能記錄整個棋盤。

 

程式碼

 1 /* 
 2 TIME: O(n!*n)    n行*每行從n 到 n-1 到 n-2...1  即 n!
 3 SPACE: O(n)
 4 */
 5 
 6 class Solution {
 7       public List<List<String>> solveNQueens(int
n) { 8 List<List<String>> result = new ArrayList<>(); 9 int[] C = new int[n]; // C[i]表示第i行皇后所在的列編號,從二維降到一維 10 dfs(C, 0, result); 11 return result; 12 } 13 private static void dfs(int[] C, int row, List<List<String>> result) { 14 int N = C.length; 15 if (row == N) { // 終止條件,也是收斂條件,意味著找到了一個可行解 16 List<String> solution = new ArrayList<>(); 17 // 第i行 18 for (int i = 0; i < N; ++i) { 19 char[] charArray = new char[N]; 20 Arrays.fill(charArray, '.'); 21 //第j列 22 for (int j = 0; j < N; ++j) { 23 if (j == C[i]) charArray[j] = 'Q'; 24 } 25 solution.add(new String(charArray)); 26 } 27 result.add(solution); 28 return; 29 } 30 31 for (int j = 0; j < N; ++j) { // 擴充套件狀態,一列一列的試 32 boolean ok = isValid(C, row, j); 33 if (!ok) continue; // 剪枝,如果非法,繼續嘗試下一列 34 // 執行擴充套件動作 35 C[row] = j; 36 dfs(C, row + 1, result); 37 // 撤銷動作 38 // C[row] = -1; 39 } 40 } 41 42 /** 43 * 能否在 (row, col) 位置放一個皇后. 44 * 45 * @param C 棋局 46 * @param row 當前正在處理的行,前面的行都已經放了皇后了 47 * @param col 當前列 48 * @return 能否放一個皇后 49 */ 50 private static boolean isValid(int[] C, int row, int col) { 51 for (int i = 0; i < row; ++i) { 52 // 在同一列 53 if (C[i] == col) return false; 54 // 在同一對角線上 55 if (Math.abs(i - row) == Math.abs(C[i] - col)) return false; 56 } 57 return true; 58 } 59 }