题目: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.."] ]
思路:回溯或者二进制法
思路很清晰,首先我是每行插入一个,所以行的问题不需要考虑,然后就是需要判断列和两个对角线的问题。判断的程序是一个难题:主要就是八个位判断
1<<colIndex 代表第几列的时候,向左移位colIndex位,如果有效(此时为0),此时就要setFlag,并操作,因为,我刚刚就是已经有代表哪几个位已经占据的标志了。至于后面的unsetFlag函数,只是通过某种数学逻辑关系进行运算,返回原来的状态。colFlag&~(1<<colIndex)。
在真正的主程序里面,首先定义rowIndex为answer的数组,一旦满了,就保存进堆栈。因为最大只能到n-1的。
首先在answer放入n个’.',然后从0到n-1 开始遍历,先是判断是否满足,不满足直接return,满足,开始更新各个flag值,此时answer已经存入一组数,满足了,可以存入堆栈,然后开始下一层,这个时候,还是从0开始一个个判断,发现,总有不能满足的。继续下一个i值。
值得注意的是,每个循环里面,在加入q之后,为了下一列的判断,还得出栈,退出q,不然程序出错。
answer的进栈和出栈也是对称的。总之,回溯法是对称的。
代码:
class Solution { private: int colFlag;//代表列 int diagFlag1;//index=i+j int diagFlag2;//index=n-1+i-j bool isValid(int rowIndex,int colIndex,int n){ //行不需要判断,因为我是按照行走的 //为0说明有效 if( (1<<colIndex)&colFlag ){ //为1 无效 return false; } if( (1<<(rowIndex+colIndex))&diagFlag1 ){ return false; } if( (1<<(n-1+rowIndex-colIndex) ) & diagFlag2 ){ return false; } return true; } void setFlag(int rowIndex,int colIndex,int n){ colFlag |=(1<<colIndex); diagFlag1 |=(1<<(rowIndex+colIndex)); diagFlag2 |=(1<<(n-1+rowIndex-colIndex)); } void unsetFlag(int rowIndex, int colIndex, int n) { colFlag &= ~(1 << colIndex); diagFlag1 &= ~(1 << (rowIndex + colIndex)); diagFlag2 &= ~(1 << (n + rowIndex - colIndex - 1)); } void queenHelper(int n, vector<string> &answer, vector<vector<string> > &result) { int rowIndex = answer.size(); if (rowIndex == n) { result.push_back(answer); return; } answer.push_back(string(n, '.')); for (int i = 0; i < n; i++) { if (isValid(rowIndex, i, n)) { setFlag(rowIndex, i, n); answer.back()[i] = 'Q'; queenHelper(n, answer, result); answer.back()[i] = '.'; unsetFlag(rowIndex, i, n); } } answer.pop_back(); } public: vector<vector<string> > solveNQueens(int n) { // https://oj.leetcode.com/problems/n-queens/ colFlag = diagFlag1 = diagFlag2 = 0; vector<vector<string> > result; vector<string> answer; queenHelper(n, answer, result); return result; } };