题目链接:https://leetcode.com/problems/n-queens/
思路:回溯法,如果你会写八皇后问题,那么这道题就很简单了。
AC 5ms Java:
具体思路注释在程序中了。
class Solution {
List<List<String>> ans=new ArrayList();
public List<List<String>> solveNQueens(int n) {
String[][] strs=new String[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
strs[i][j]=".";//初始化二维数组
backtrace(0,n,strs);
return ans;
}
public void backtrace(int row,int n,String[][] strs){
if(row>n-1){//当行数大于N-1时,说明已经找到了一组解。
List<String> list=new ArrayList();
for(int i=0;i<n;i++){
StringBuilder sb=new StringBuilder();
for(int j=0;j<n;j++){
sb.append(strs[i][j]);
}
list.add(sb.toString());
}
ans.add(list);
}
for(int col=0;col<n;col++){
if(check(strs,row,col)){//检查通过时,继续递归下一行
strs[row][col]="Q";
backtrace(row+1,n,strs);
strs[row][col]=".";//注意别忘了再更新回来。
}
}
}
public boolean check(String[][] strs,int row,int col){
int n=strs.length;
for(int t=0;t<n;t++){//检查列冲突
if(strs[t][col].equals("Q"))
return false;
}
for(int t=0;t<n;t++){//检查行冲突
if(strs[row][t].equals("Q"))
return false;
}
for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
if(strs[i][j].equals("Q"))//检查左上对角线冲突
return false;
}
for(int i=row-1,j=col+1;i>=0&&j<n;i--,j++){
if(strs[i][j].equals("Q"))//检查右上对角线冲突
return false;
}
return true;
}
}
我的程序有两个地方还可以优化,一个是二维数组初始化哪里,
另一个就是当此数组满足条件时添加结果到ans里。
*********************************************************************************************************************************************************************************************************二更的华丽分界线*****************************************************************************
后来发现用char数组代替String数组在速度上要快不少。
AC 3ms beats 96% Java:
class Solution {
List<List<String>> ans=new ArrayList();
public List<List<String>> solveNQueens(int n) {
char[][] chars=new char[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
chars[i][j]='.';//初始化二维数组
backtrace(0,n,chars);
return ans;
}
public void backtrace(int row,int n,char[][] chars){
if(row>n-1){//当行数大于N-1时,说明已经找到了一组解。
List<String> list=new ArrayList();
for(int i=0;i<n;i++){
StringBuilder sb=new StringBuilder();
for(int j=0;j<n;j++){
sb.append(String.valueOf(chars[i][j]));
}
list.add(sb.toString());
}
ans.add(list);
return;
}
for(int col=0;col<n;col++){
if(check(chars,row,col)){//检查通过时,继续递归下一行
chars[row][col]='Q';
backtrace(row+1,n,chars);
chars[row][col]='.';//注意别忘了再更新回来。
}
}
}
public boolean check(char[][] chars,int row,int col){
int n=chars.length;
for(int t=0;t<n;t++){//检查列冲突
if(chars[t][col]=='Q')
return false;
}
for(int t=0;t<n;t++){//检查行冲突
if(chars[row][t]=='Q')
return false;
}
for(int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
if(chars[i][j]=='Q')//检查左上对角线冲突
return false;
}
for(int i=row-1,j=col+1;i>=0&&j<n;i--,j++){
if(chars[i][j]=='Q')//检查右上对角线冲突
return false;
}
return true;
}
}