LeetCode 51 N皇后
51.N皇后
按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位
双hash+回溯递归
此处采取逐行去填充元素位置的方式:
bool col[9]={false};
记录那些列被使用了,通过记录和逐行填充的方式实现了行列的不冲突
vector<pair<int,int>> pos;
记录每一行所使用的列号用于判断是否会出现的在同一斜线上
基本的递归流程:递归的参数为 n,cur
分表表示皇后的个数和当前处理的行数(从0开始),那么当 cur==n
时递归结束,将本次递归的结果集加入到结果集中。 cur
行放置位置的选取,从0开始逐个判断,是否和前面已选元素在同行和同列,或者在一条斜线上,不是则选取后递归,递归返回后再进行回溯。
是否在同一斜线上的判断:利用 pos
数组进行判断,主要是看二维坐标中的点,行距和列距是否相同。
1 2 3 4 5 6 7
| bool isSlash(int i,int j){ if(pos.empty()) return false; for(auto &a:pos){ if(abs(a.first-i)==abs(a.second-j)) return true; } return false; }
|
总体代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| class Solution { public: vector<vector<string>> res; vector<string> tmp; bool col[9]={false}; vector<pair<int,int>> pos; bool isSlash(int i,int j){ if(pos.empty()) return false; for(auto &a:pos){ if(abs(a.first-i)==abs(a.second-j)) return true; } return false; } void DFS(int cur,int n){ if(cur==n){ res.push_back(tmp); return; } for(int i=0;i<n;i++){ if(!col[i]&&!isSlash(cur,i)){ col[i]=true; pos.push_back({cur,i}); string s(n,'.'); s[i]='Q'; tmp.push_back(s); DFS(cur+1,n); col[i]=false; tmp.pop_back(); pos.pop_back(); } } } vector<vector<string>> solveNQueens(int n) { DFS(0,n); return res; } };
|