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

这是一道典型的NP问题,基本思路如下就是递归加回溯:

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

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

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

但有几个问题需要注意,首先要注意返回类型是List<List<String>>,也就是List of List,在生成时一定要这么写

List<List<String>> res = new ArrayList<List<String>>();

否则会报错。

其次注意declare helper function 时,argument 要写成 

List<List<String>> res

还有就是用到了新的class StringBuilder, 其sb.append("Hello!")和sb.toString()非常好用。

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 }

 

你可能感兴趣的:(LeetCode N-Queens)