牛客网刷题-N皇后问题

问题描述

N皇后问题是指在N*N的棋盘上要摆N个皇后,
要求:任何两个皇后不同行,不同列也不再同一条斜线上,
求给一个整数N,返回N皇后的摆法数。

示例

示例1

输入
8

输出
92

解决思路

思路

在这里插入图片描述

  1. 回溯法:要保证n个皇后不同行,不同列,不同斜线,只需要满足下面3个条件即可
    (1)N个皇后不同行,通过s1存储该行上的皇后
    (2)N个皇后不同左上角如图斜线方向,通过s2存储该方向的皇后。我们会发现位于统一斜线上的坐标满足,x坐标和y坐标的和相等。例如:(1,0) (0,1)在同一斜线上,和均为1
    (3)N个皇后不同右下角如图斜线方向,通过s3存储该方向的皇后。我们会发现位于统一斜线上的坐标满足,x坐标和y坐标的差相等。例如:(5,0) (6,1)在同一斜线上,差均为5

代码实现

// 思路1
public class Solution {
    
      
    private int count;
    /**
     * @param n int整型 the n
     * @return int整型
     */
    public int Nqueen (int n) {
    
    
        // write code here
        count = 0;
        Set<Integer> s1 = new HashSet<>(), s2 = new HashSet<>(), s3 = new HashSet<>();
        Nqueen(n, 0, s1, s2, s3);
        return count;
    }

    public void Nqueen (int n, int row, Set<Integer> s1, Set<Integer> s2, Set<Integer> s3) {
    
    
        if (row == n) {
    
    
            count++;
            return;
        } else {
    
    
            for (int i = 0; i < n; i++) {
    
    
                // 判断是否同行
                if (s1.contains(i)) {
    
    
                    continue;
                }

                // 判断左上角方向
                int d1 = row + i;
                if (s2.contains(d1)) {
    
    
                    continue;
                }

                // 判断左下角方向
                int d2 = row - i;
                if (s3.contains(d2)) {
    
    
                    continue;
                }

                s1.add(i);
                s2.add(d1);
                s3.add(d2);
                Nqueen(n, row + 1, s1, s2, s3);
                s1.remove(i);
                s2.remove(d1);
                s3.remove(d2);
            }
        }
    }
}

时间复杂度分析:
O(N!):其中 N 是皇后数量。

空间复杂度分析:
O(N):其中 N 是皇后数量。空间复杂度主要取决于递归调用层数、记录每行放置的皇后的列下标的数组以及三个集合,递归调用层数不会超过 N,每个集合的元素个数都不会超过 N。

小伙伴如果想测试的话,可以直接到牛客网这个链接做测试

N皇后问题-牛客网(ps:文件的解法会超时,效果版可以参考题解,这里说的主要是方法)

猜你喜欢

转载自blog.csdn.net/qq_35398517/article/details/114277792