原题链接在此: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.