LeetCode 51. N-Queens

原题链接在此:https://leetcode.com/problems/n-queens/

题目:

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.."]
]

题解:

DFS+recursion. 用递归处理子问题,当某一个子问题出错时就回溯到上一层。这类问题的时间复杂度都是指数量级的。

在子问题中,列出一种例子,判断当前情况是否合法,如果不合法就回到上一层,如果合法就DFS到下一层,当填满后就保存此正确结果。然后去掉最后添加的数,列举其他方法。但本题中不需要去掉就是因为此题是用一个一维数组代表棋盘,每个index代表行, value 代表列.

[2,0,1,3] 代表[0,2],[1,0],[2,1],[3,3]上有皇后。

Time Complexity: NP问题都是exponential的. Space: O(n), 新建了row. Recursion 用了n层stack.

AC Java:

 1 public class Solution {
 2     public List<List<String>> solveNQueens(int n) {
 3         List<List<String>> res = new ArrayList<List<String>>();
 4         if(n<=0){
 5             return res;
 6         }
 7         helper(n, 0, new int[n], res);
 8         return res;
 9     }
10     private void helper(int n, int cur, int [] row, List<List<String>> res){
11         //cur stands for current position of row
12         //这里表示这一条已经加到头了
13         if(cur == n){
14             List<String> item = new ArrayList<String>();
15             for(int i = 0; i<row.length; i++){
16                 StringBuilder sb = new StringBuilder();
17                 for(int j = 0; j<row.length; j++){
18                     if(row[i] != j){
19                         sb.append('.');
20                     }else{
21                         sb.append('Q');
22                     }
23                 }
24                 item.add(sb.toString());
25             }
26             res.add(item);
27             return;
28         }
29         
30         //没到头时就从0到n挨个试着加入row
31         for(int i = 0; i<n; i++){
32             row[cur] = i;
33             //检查到目前的cur位置时, row是否合法
34             if(isValid(cur, row)){
35                 helper(n, cur+1, row, res);
36             }
37         }
38     }
39     
40     private boolean isValid(int cur, int [] row){
41         for(int i = 0; i<cur; i++){
42             if(row[i] == row[cur] || Math.abs(row[cur] - row[i]) == cur-i){
43                 return false;
44             }
45         }
46         return true;
47     }
48 }

AC Python:

 1 class Solution:
 2     def solveNQueens(self, n: int) -> List[List[str]]:
 3         res = []
 4         if n <= 0:
 5             return res
 6         board = [0] * n
 7         self.dfs(n, board, 0, res)
 8         return res
 9     
10     def dfs(self, n: int, board: List[int], ind: int, res: List[List[str]]) -> None:
11         if ind == n:
12             res.append(self.construct(board))
13             return
14         
15         for i in range(n):
16             board[ind] = i
17             if self.isValid(ind, board):
18                 self.dfs(n, board, ind + 1, res)
19         
20     def construct(self, board: List[int]) -> List[str]:
21         res = []
22         for i in range(len(board)):
23             item = ["."] * len(board)
24             item[board[i]] = "Q"
25             res.append("".join(item))
26         
27         return res
28     
29     def isValid(self, cur: int, board: List[int]) -> bool:
30         for i in range(0, cur):
31             if board[i] == board[cur] or abs(board[cur] - board[i]) == cur - i:
32                 return False
33             
34         return True

跟上N-Queens II.

posted @ 2015-07-22 05:09  Dylan_Java_NYC  阅读(751)  评论(0编辑  收藏  举报