[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..”]
]
题意:该题是n皇后问题,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
思路:很明显每一行每一列都只能有一个皇后,否则一行中出现两个皇后或者一列中出现两个皇后,她们就可以互相攻击了。还需要满足的条件是任意两个皇后不在同一列上。
该题采用回溯的方法,与前面字符串的全排列类似。有n个皇后就用一个一维数组A[n]表示,初始化时A[i] = i;代表的意思是第i行的皇后在第i列。第一行的皇后所在的列可能是第1到第n列(比如选择了第k列),那么第二行的皇后有n-1个列可以选,只要不在第k列,以此类推。每一行确定一个皇后的列的位置的时候需要判断与前面确定的皇后是否在一个斜线上,不在的话才会递归到下一行。

class Solution {
public:
    vector<vector<string> > solveNQueens(int n) {
        vector<vector<string>> result;
        if(n <= 0)return result;
        else if(n == 1){
            vector<string> temp;
            temp.push_back("Q");
            result.push_back(temp);
            return result;
        }
        vector<int> QueenInRows;
        vector<string> res;
        for(int i = 0; i < n ; i++){
            QueenInRows.push_back(i);
            res.push_back(string(n,'.'));
            res[i][i] = 'Q';
        }
        getAllResult(result,0,QueenInRows,res);
        return result;
    }
    void getAllResult(vector<vector<string>>& result,int i, vector<int>& QueenInRows,vector<string> & temp){
        if(i == QueenInRows.size() - 1){
           for(int k = 0; k < i; k++)
                if(abs(QueenInRows[k] - QueenInRows[i]) == abs(i-k))return;//判断最后一行的皇后是否与其他行的皇后在同一条斜线上。
            result.push_back(temp);
            return;
        }
        for(int j = i; j < QueenInRows.size(); j++){
            swap(QueenInRows[i],QueenInRows[j]);
            bool goout = false;
            for(int k = 0; k < i; k++){//判断该行的皇后放置的列的位置是否与其他行的皇后在同一条斜线上。
                if(abs(QueenInRows[k] - QueenInRows[i]) == abs(i-k)){
                    swap(QueenInRows[i],QueenInRows[j]);
                    goout  = true;
                    break;
                }
            }
            if(goout)continue;
            swap(temp[i],temp[j]);
            getAllResult(result,i+1,QueenInRows,temp);
            swap(QueenInRows[i],QueenInRows[j]);
            swap(temp[i],temp[j]);
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值