【LeetCode】52. N皇后 II

一、题目

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
queens
上图为 8 皇后问题的一种解法。

给定一个整数 n,返回 n 皇后不同的解决方案的数量。

示例:

输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]

提示:

  • 皇后,是国际象棋中的棋子,意味着国王的妻子。皇后只做一件事,那就是“吃子”。当她遇见可以吃的棋子时,就迅速冲上去吃掉棋子。当然,她横、竖、斜都可走一或 N-1 步,可进可退。(引用自 百度百科 - 皇后 )

二、解决

1、直接返回

思路:

直接用已有程序计算出结果,然后放入数组,需要时直接返回。有点讨巧,但实际可以与第二种方法结合使用,加快访问。

代码:

int totalNQueens(int n) {
    
    
    int ans[] = {
    
    1, 0, 0, 2, 10, 4, 40, 92, 352, 724, 2680, 14200, 73712, 365596, 2279184, 14772512, 95815104, 666090624};
    return ans[n - 1];
}

时间复杂度: O(1)
空间复杂度: O(n)

2、DFS

思路:

逐行扫描,不合格回溯。更具体请看:【LeetCode】51. N 皇后

代码:

class Solution {
    
    
    int cnt = 0;
    boolean[] cols;
    boolean[] diag1;
    boolean[] diag2;
    public int totalNQueens(int n) {
    
    
        cols = new boolean[n];
        diag1 = new boolean[2*n];
        diag2 = new boolean[2*n];
        DFS(0, n);
        return cnt;
    }

    private void DFS(int row, int n) {
    
    
        if (row==n) {
    
    
            cnt++;
        }
        for (int col=0; col<n; col++) {
    
    
            if (cols[col] || diag1[row-col+n] || diag2[row+col])  continue;
            cols[col]=true; diag1[row-col+n]=true; diag2[row+col]=true;
            DFS(row+1, n);
            cols[col]=false; diag1[row-col+n]=false; diag2[row+col]=false;
        }
    }
}

时间复杂度: O(n!),n为皇后数量。
空间复杂度: O(n),递归调用层数,最多n层。

3、位运算

思路:

理解不容易,暂时搁置。

代码:

class Solution {
    
    
  
  private int size;
  private int count;

  private void solve(int row, int ld, int rd) {
    
    
    if (row == size) {
    
    
      count++;
      return;
    }
    int pos = size & (~(row | ld | rd));
    while (pos != 0) {
    
    
      int p = pos & (-pos);
      pos -= p;
      solve(row + p, (ld + p) << 1, (rd + p) >> 1);
    }
  }
  
  public int totalNQueens(int n) {
    
    
    count = 0;
    size = (1 << n) - 1;
    solve(0, 0, 0);
    return count;  
  }
}

时间复杂度: O ( ? ) O(?) O(?)
空间复杂度: O ( ? ) O(?) O(?)

三、参考

1、Accepted Java Solution
2、Easiest Java Solution (1ms, 98.22%)
3、Collection of solutions in Java
4、A nice hack (might be very informative specially for new users)
5、Java AC, bit M, over 98%, low space
6、JAVA - Clean Bitwise Implementation - Beats 100% - 0ms

猜你喜欢

转载自blog.csdn.net/HeavenDan/article/details/108564488