Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
和前一题的解题思路一样,就是返回值的处理不同而已。
代码如下:
class Solution {
public:
int totalNQueens(int n) {
vector<vector<string>> result;
vector<string> answer(n,string(n,'.'));
int count = 0;
Queens(result,answer,0,n,count);
return count;
}
bool valid(vector<string>& answer,int row,int col,int n)
{
for(int i=0;i<row;i++)
if(answer[row][i] == 'Q')
return false;
for(int i=0;i<n;i++)
if(answer[i][col] == 'Q')
return false;
for(int i=row,j=col;i>=0&&j>=0;i--,j--)
if(answer[i][j] == 'Q')
return false;
for(int i=row,j=col;i>=0&&j<n;i--,j++)
if(answer[i][j] == 'Q')
return false;
return true;
}
void Queens(vector<vector<string>>& result,vector<string>& answer,int row,int n,int &count)
{
if(row == n)
{
count++;
return;
}
for(int col =0;col<n;col++)
{
if(valid(answer,row,col,n))
{
answer[row][col] = 'Q';
Queens(result,answer,row+1,n,count);
answer[row][col] = '.';
}
}
}
};
因为不需要存储正解的矩阵,所以为了节省空间,可以不使用O(n*n)的内存空间,从而进行优化。关键是对角线上的情况如何处理:可以发现在45度角的对角线上的元素的行号和列号的差是相等的,对于行号和列号的差为负数的情况,我们通过对其加上n来进行转换,而在135度角的对角线上的元素的行号和列号的和是相等的。
代码如下:
class Solution {
public:
int totalNQueens(int n) {
bool* cols = new bool[n];
bool* dg1 = new bool[2*n];
bool* dg2 = new bool[2*n];
memset(cols,false,sizeof(bool)*n);
memset(dg1,false,sizeof(bool)*n*2);
memset(dg2,false,sizeof(bool)*n*2);
int count = 0;
Queens(cols,dg1,dg2,0,n,count);
return count;
}
void Queens(bool* cols,bool* dg1,bool* dg2,int row,int n,int &count)
{
if(row == n)
{
count++;
return;
}
for(int col =0;col<n;col++)
{
int index1 = col+row;
int index2 = col-row+n;
if(cols[col] || dg1[index1] || dg2[index2])
continue;
cols[col] = true; dg1[index1] = true; dg2[index2] = true;
Queens(cols,dg1,dg2,row+1,n,count);
cols[col] = false; dg1[index1] = false; dg2[index2] = false;
}
}
};