[Leetcode] 51. 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的内部实现了安全性检查:即在搜索进行到第k层的第i个位置时,我们检查它所在的列是否安全;所在的对角线是否安全,以及所在的反对角线是否安全。如果这三个地方都是安全的,则试图在该位置放置一个皇后,然后接着搜索下一层。搜索完成之后一定要回溯,才能保证找到所有满足条件的解。

代码

class Solution {
public:
    vector<vector<string>> solveNQueens(int n) {
        vector<vector<string>> ret;
        if(n <= 0) 
            return ret;
        vector<string> map(n, string(n, '.'));  // initialize the chess
        DFS(map, ret, 0, n);  
        return ret;
    }
private:
    void DFS(vector<string>& map, vector<vector<string>> &ret, int k, int n)  
    {  
        if(n == k) 
            return ret.push_back(map);  
        for(int i = 0; i < n; ++i)  
        {
            int x, y;
            for(y = 0; y < k; y++)               
                if(map[y][i] == 'Q')    // the y-th row is not safe
                    break;  
            if(y != k)
                continue;  
            for(x = i, y = k; x < n && y >= 0; x++, y--)  
                if(map[y][x] == 'Q')    // the counter-diagonal is not safe
                    break;  
            if(!(x == n || y < 0))
                continue;  
            for(x = i, y = k;x >= 0 && y >= 0; x--, y--)  
                if(map[y][x] == 'Q')    // the diagonal is not safe 
                    break;  
            if(!(x < 0 || y < 0))
                continue;  
            map[k][i] = 'Q';  
            DFS(map, ret, k + 1, n);  
            map[k][i] = '.';            // backtracking
        }  
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值