题目来源
问题描述
N皇后问题是指在N∗N的棋盘上摆N个皇后
要求:任何两个皇后不同行,不同列也不再同一条斜线上
返回:一个整数N,返回N皇后的摆法数
问题思路
本人能力有限只能想到用回溯法求解,回溯法的思想和和暴力穷举类似,但不同的是回溯法设置了中止结果,当运行到某一步发现不可行的时候就会回退一步,从而减少了开销。就像走迷宫,记录每一个岔口,当我发现某条路前面的路不通时,就返回上一个岔口选择另一条路,若这个岔口的路全部不通,就再回到前一个岔口,选择另一条路径。
以4皇后为例子,首先将第一个皇后落在第一行第一列,剩下可放的位置只有白色区域
假设我们将第二个皇后放在如下图的位置,那么只剩下一块白色区域,放置了第三个皇后以后,就没有位置可以再放皇后了,于是我们回到上图,选择第二行第四列的位置进行尝试,重复这样的尝试,直到四个皇后都被放置在棋盘内,则count+1。
同样由于水平的限制,本人还只会利用迭代实现回溯,下面是上代码:
class Solution {
public:
/**
*
* @param n int整型 the n
* @return int整型
*/
//判断当前棋盘上r和c是否可以放置皇后,不需要判断行因为每次都选择下一行放置皇后
bool canplace(vector<vector<int> > board,int r,int c){
// 若同一列上有皇后
for(int i=0;i<r;i++){
if(board[i][c]==1)
return false;
}
// 若斜向下的对角线上有皇后
for(int i=r-1,j=c-1;i>=0&&j>=0;i--,j--){
if(board[i][j]==1)
return false;
}
// 若斜向上的对角线上有皇后
for(int i=r-1,j=c+1;i>=0&&j<board.size();i--,j++){
if(board[i][j]==1)
return false;
}
return true;
}
// 迭代实现回溯
void helper(vector<vector<int> > board,int row,int &res){
// 当所有皇后都被放置在棋盘上时
if(row == board.size()) {res++;return ;}
// 从第一列开始遍历能否放置皇后
for(int i=0;i<board[0].size();i++){
if(canplace(board,row,i)){
board[row][i] = 1;
helper(board,row+1,res);
board[row][i] = 0;
}
}
}
int Nqueen(int n) {
if(n==1)return 1;
// 将board全部置为0
vector<vector<int> > board(n, vector<int>(n, 0));
int res = 0;
helper(board,0,res);
return res;
}
};
如果需要在vs里运行,需要在前面加上
#include <iostream>
#include <vector>
using namespace std;
以及main函数调用
int main() {
int n;
cin >> n;
Solution s;
cout << s.Nqueen(n) << endl;
return 0;
}
运行结果
运行时间:30ms
超过52.49%用C++提交的代码
占用内存:404KB
超过47.41%用C++提交的代码
总结
第一篇算法博客到此为止,希望以后一定要坚持。
除此之外还有些话想说,很惭愧读到了研才开通自己的技术博客,本科的时候只想着期末复习一下考个高分,拿着好看点的成绩单申请个英国硕士快点读完回国考公,后来发现这条路不太好走。可惜了大学四年蹉跎没好好学习技术,均分考得高也没什么用,知识都还给老师了,现在找工作要全部自己重新拾起也挺不容易的,希望为时未晚,春招能有一个满意的结果。