【LeetCode】104.N-Queens II

题目描述(Hard)

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.

题目链接

https://leetcode.com/problems/n-queens-ii/description/

Example 1:

Input: 4
Output: [
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.

算法分析

设置一个数组vector<int>C(n, 0), C[i]表示第i行皇后所在的列编号,即在位置(i, C[i])上放了一个皇后,这样用一个一维数组就能记录整个棋盘。

方法一:对当前行,每次逐列扫描,判断所在位置是否放置皇后(前面的行的皇后是否冲突),判断条件,对第i行: 1.是否在同一列C[i]==col;2.是否在同一对角线abs(row-i)==abs(col-C[i]),即两点不构成正方形,就不在一条对角线上。时间复杂度O(n!*n),空间复杂度O(n)

方法二:记录皇后已经占据的列,占据的主对角线、副对角线,对N×N的棋盘,主对角线和副对角线各2N-1条。对第row行,第i列数据,其所在主对角线位置为row-j+N-1,其所在副对角线的位置为row+j。时间复杂度O(n!),空间复杂度O(n)

提交代码(方法一):

class Solution {
public:
    int totalNQueens(int n) {
        this->solutions = 0;
        vector<int> C(n, -1);
        dfs(C, 0);
        return this->solutions;
    }

private:
    int solutions;
    void dfs(vector<int> &C, int row) {
        const int N = C.size();
        if (row == N) {
            ++this->solutions;
            return;
        }

        // 逐列扫描
        for (int i = 0; i < N; ++i) {
            if (!isValid(C, row, i)) continue;
            C[row] = i; 
            dfs(C, row + 1);
            C[row] = -1;
        }
    }

    bool isValid(vector<int>& C, int row, int col) {
        for (int i = 0; i < row; ++i) {
            // 如果在相同列
            if (C[i] == col) return false;
            // 在对角线上
            if (abs(row - i) == abs(col - C[i])) return false;
        }

        return true;
    }
};

    

提交代码(方法二):

class Solution {
public:
    int totalNQueens(int n) {
        columns = vector<bool>(n, false);
        main_diag = vector<bool>(2 * n - 1, false);
        anti_diag = vector<bool>(2 * n - 1, false);
        this->solutions = 0;
        vector<int> C(n, -1);
        dfs(C, 0);
        return this->solutions;
    }
    
private:
    int solutions;
    vector<bool> columns;
    vector<bool> main_diag;
    vector<bool> anti_diag;
    void dfs(vector<int> &C, int row) {
        const int N = C.size();
        if (row == N) {
            ++this->solutions;
        }
        
        // 逐列扫描
        for (int i = 0; i < N; ++i) {
            bool valid =  !columns[i] && !main_diag[row - i + N - 1]
                && !anti_diag[row + i];
            if (!valid) continue;
            columns[i] = main_diag[row - i + N - 1] 
                = anti_diag[row + i] = true;
            C[row] = i; 
            dfs(C, row + 1);
            C[row] = -1;
            columns[i] = main_diag[row - i + N - 1] 
                = anti_diag[row + i] = false;
        }
    }
};

    

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博沟通,博会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博沟通,博会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博沟通,博会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博沟通,博会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博沟通,博会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博沟通,博会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博沟通,博会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博沟通,博会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值