三道题跳两道,做一下N皇后,剩下两道等60天结束后再看,目前跳过的还有字符串的KMP算法
51. N皇后
文字讲解/题目链接:
解题思路
难点在于,这题是一个二维的棋盘,并且很难想到回溯的算法
我们横向搜索的列,深度搜索的是行,在每一行去填列,看懂这个思路就比较简单了
图中可以看出,递归深度就是我们棋盘的维度,然后可以看出我们是在叶子节点取结果,剩下的细节写在代码中了
class Solution {
private:
vector<vector<string>> result; //三维数组
bool isValid(int row, int col, vector<string>& chessborad , int n)
{
//行不用检查,因为每次for循环时,只会选一个元素
//列
for(int i=0;i<row;i++){ //检查放这个元素之前的行是否有皇后
if(chessborad[i][col]=='Q') return false;
}
//判断左上45度是否有重复。主对角线
for(int i=row-1 , j = col -1 ;i >=0&&j>=0 ; i-- , j--)
{
if(chessborad[i][j]=='Q') return false;
}
//判断左下45度,副对角线,这里n是从0开始的,因此不能取到
for(int i = row-1 , j =col +1 ; i>=0&&j< n ; i-- , j++)
{
if(chessborad[i][j]=='Q') return false;
}
return true;
}
void backtracking(int n , int row , vector<string>& chessborad) //参数分别是几维,行和棋盘
{
if(row==n) //当我们的行和n的维度对应了,说明已经递归到底了,因为我们是先判断合法再放的,因此在这收集结果
{
result.push_back(chessborad);
return;
}
for(int col=0; col<n; col++)
{
if(isValid(row,col,chessborad,n))
{
chessborad[row][col] = 'Q';
backtracking(n,row+1,chessborad); //这里是从下一行开始搜索,相当于startIndex
chessborad[row][col] = '.'; //撤销皇后
}
}
}
public:
vector<vector<string>> solveNQueens(int n) {
vector<string> chessborad(n,string(n,'.')); //二维棋盘并初始化
backtracking(n,0,chessborad);
return result;
}
};