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.."] ]
n皇后问题就是找到所有的可行解,首先应该有一个判断是否可以在当前位置放置Q的函数,称作valid,然后一行一行的放置Q,在每一行放置Q的时候,都从i到n遍历一遍,因为Q放在任一个位置都是可能的,所以为了找全都要便利一遍,需要注意的是,在这一行的这个位置放置完之后,去查看下一行放置,再返回本行时,记得将这个位置的Q拿掉:
public List<List<String>> solveNQueens(int n) {
List<List<String>> result = new ArrayList<List<String>>();
char[][] index = new char[n][n];
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
index[j][k]='.';
}
placeOk(index,0,n,result);
return result;
}
private void placeOk(char[][] index, int x, int n, List<List<String>> result) {
// TODO Auto-generated method stub
if(x==n)
{
List<String> s = new ArrayList<>();
for(int i=0;i<n;i++)
{
String t= new String(index[i]);
s.add(t);
}
result.add(s);
return;
}
for(int i=0;i<n;i++)
{
if(valid(index,x,i,n))
{
index[x][i]='Q';
placeOk(index,x+1,n,result);
index[x][i]='.';
}
}
}
private boolean valid(char[][] index, int x, int y,int n) {
// TODO Auto-generated method stub
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(index[i][j]=='Q' && (x==i||y==j||Math.abs(i-x)==Math.abs(j-y)))
return false;
}
return true;
}
另一种解法就是,初始化的时候用Boolean的数组,用FALSE表示未放置,TRUE表示放置了Q:
public List<List<String>> solveNQueens(int n) {
List<List<String>> result = new ArrayList<List<String>>();
boolean[][] index = new boolean[n][n];
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
index[j][k]=false;
}
for(int i=0;i<n;i++)
{
placeOk(index,0,i,n,result);
index[0][i]=false;
}
return result;
}
private void placeOk(boolean[][] index, int row, int colum,int n, List<List<String>> result) {
// TODO Auto-generated method stub
if(valid(index,row,colum))
{
index[row][colum]=true;
if(row==n-1)
{
//添加list;
List<String> t = new ArrayList<String>();
for(int i=0;i<n;i++)
{
String temp = "";
for(int j=0;j<n;j++)
{
if(index[i][j]==true)
temp+="Q";
else
temp+=".";
}
t.add(temp);
}
result.add(t);
return;
}
else
{
index[row][colum]=true;
for(int i=0;i<n;i++)
{
placeOk(index,row+1,i,n,result);
index[row+1][i]=false;
}
}
}
return;
}
private boolean valid(boolean[][] index, int row, int colum) {
// TODO Auto-generated method stub
for(int i=0;i<index.length;i++)
for(int j=0;j<index.length;j++)
{
if(index[i][j])
{
if(i==row)
return false;
else if(j==colum)
return false;
else if(Math.abs(i-row)==Math.abs(j-colum))
return false;
}
}
return true;
}
第52题是返回有多少个解的数值,可以直接在51的基础上,返回resul.size(),或者定义一个全局变量count,在每次找到完整的存放方式之后,count++:
public class Solution {
int count = 0;
public int totalNQueens(int n) {
List<List<String>> result = new ArrayList<List<String>>();
char[][] index = new char[n][n];
for(int j=0;j<n;j++)
{
for(int k=0;k<n;k++)
index[j][k]='.';
}
placeOk(index,0,n,result);
return count;
}
private void placeOk(char[][] index, int x, int n, List<List<String>> result) {
// TODO Auto-generated method stub
if(x==n)
{
count++;
return;
}
for(int i=0;i<n;i++)
{
if(valid(index,x,i,n))
{
index[x][i]='Q';
placeOk(index,x+1,n,result);
index[x][i]='.';
}
}
}
private boolean valid(char[][] index, int x, int y,int n) {
// TODO Auto-generated method stub
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
if(index[i][j]=='Q' && (x==i||y==j||Math.abs(i-x)==Math.abs(j-y)))
return false;
}
return true;
}
}