N皇后问题是把N个皇后放在一个N×N棋盘上,使皇后之间不会互相攻击。
给出一个整数n,返回n皇后问题的所有摆放方案
例如:
4皇后问题有两种摆放方案
[".Q..", // 解法 1 "...Q", "Q...", "..Q."], ["..Q.", // 解法 2 "Q...", "...Q", ".Q.."] ]
import java.util.*;
public class Solution {
//结果集
ArrayList<String[]> res = new ArrayList<String[]>();
public ArrayList<String[]> solveNQueens(int n) {
if(n==0){
return res;
}
// '.' 表示空,'Q' 表示皇后,初始化空棋盘。
String[][] board = new String[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
board[i][j]=".";
}
backtrack(board, 0);
return res;
}
void backtrack(String[][] board, int row){
//结束条件
if(row == board.length){
int n = board.length;
String[] tmp = new String[n];
for(int i=0;i<n;i++){
tmp[i]="";
for(int j=0;j<n;j++){
tmp[i] += board[i][j];
}
}
res.add(tmp);
return;
}
//循环递归
for(int col=0; col<board[row].length; col++){
//决策树判断,排除不合法的下棋位置
if(!isValid(board, row, col)){
continue;
}
//做选择
board[row][col] = "Q";
//进入下一行决策树
backtrack(board, row+1);
//撤销选择
board[row][col] = ".";
}
}
boolean isValid(String[][] board, int row, int col){
int n = board.length;
//检查列是否有皇后互相冲突
for(int i=0; i<n; i++){
if(board[i][col] == "Q")
return false;
}
//检查右上方
for(int i=row-1, j=col+1; i>=0&&j<n; i--,j++){
if(board[i][j] == "Q")
return false;
}
//检查左上方
for(int i=row-1, j=col-1; i>=0&&j>=0; i--,j--){
if(board[i][j] == "Q")
return false;
}
return true;
}
} /** 使用一维数组 leetcode 通过 :Runtime: 2 ms, faster than 97.02% of Java online */ class Solution { public List<List<String>> solveNQueens(int n) { List<List<String>> res = new ArrayList(); int [] visit = new int[n]; dfs(res,visit,0,n); return res; } private void dfs(List<List<String>> res,int [] visit,int row,int n){ if(row == n){ List<String> t = new ArrayList(); char [] temp = new char[n]; int count = 0; while(count < n){ for(int j = 0;j<n;j++){ if(visit[count] == j){ temp[j] = 'Q'; }else{ temp[j] = '.'; } } t.add(new String(temp)); count++; } res.add(t); return; } for(int col=0;col<n;col++){ if(isValid(row,col,n,visit)){ visit[row] = col; dfs(res,visit,row+1,n); } } } private boolean isValid(int row,int col,int n,int [] visit){ for(int i=0;i<row;i++){ if(visit[i] == col || Math.abs(i-row) == Math.abs(visit[i]-col)){ return false; } } return true; } }
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
ArrayList<String[]> ret = new ArrayList<>();
public ArrayList<String[]> solveNQueens(int n) {
if(n <= 0) return ret;
int[] array = new int[n];
helper(array, 0);
return ret;
}
//A[i] = j 表示 i 行 j 列 上放置了一个皇后
public boolean check(int[] array,int k){
//验证新加入的第k行是否可以
for(int i = 0;i < k; i++){
if(array[i] == array[k] || k - i == Math.abs(array[k] - array[i])) return false;
}
return true;
}
public void helper(int[] array,int k){
if(k == array.length){
String[] s = new String[array.length];
for(int i = 0;i < array.length;i++){
char[] ca = new char[array.length];
Arrays.fill(ca, '.');
ca[array[i]] = 'Q';
s[i] = new String(ca);
}
ret.add(s);
return;
}
for(int i = 0;i< array.length;i++){
array[k] = i;
if(check(array,k)){
helper(array, k + 1);
}
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import java.util.ArrayList;public class NQueen { public static void main(String[] args) { NQueen nQueen = new NQueen(); ArrayList<String[]> lists = nQueen.solveNQueens(4); } public ArrayList<String[]> solveNQueens(int n) { ArrayList<String[]> results = new ArrayList<>(); if (n <= 0) { return results; } if (n == 1) { String[] strings = new String[1]; strings[0] = "Q"; results.add(strings); return results; } int k = 1; // k表示当前行 int[] x = new int[n+1]; //x[k] 表示当前列 while (k>0) { x[k] = x[k] + 1; while ((x[k] <= n) && !place(k, x)) { //跳出循环表示:当前位置k可以放或者超出 x[k] = x[k] + 1; // 不能放在该位置,判断下一列 } if (x[k] <= n) { //找到满足皇后的位置 if (k == n){ //最后一个皇后找到位置 String[] strings = new String[n]; for (int i = 1; i < n+1; i++) { StringBuffer sb = new StringBuffer(); for (int j = 0; j < n; j++) { sb.append("."); } sb.setCharAt(x[i]-1, 'Q'); strings[i-1] = sb.toString(); //System.out.print(x[i] + " "); } results.add(strings); }else{ k = k + 1; x[k] = 0; // 列重置 } }else//未找到满足皇后的位置 k = k - 1; //回溯 } return results; } // 约束条件,判断当前位置可不可以放 private boolean place(int k, int[] x) { int i = 1; while (i < k) { if (x[i] == x[k] || Math.abs(x[i] - x[k]) == Math.abs(i-k)) { return false; } ++i; } return true; }} |
import java.util.*;
public class Solution {
ArrayList<String[]> list = new ArrayList<String[]>();
public ArrayList<String[]> solveNQueens(int n) {
char[][] res = new char[n][n];
for(char[] chs : res)
Arrays.fill(chs, '.');
int[] cols = new int[n];
int[] slash1 = new int[2*n-1];
int[] slash2 = new int[2*n-1];
DFS(res, n, 0, cols, slash1, slash2);
return list;
}
public void DFS(char[][] res, int n, int cur, int cols[], int slash1[], int slash2[]) {
if(cur == n) {
String[] s = new String[n];
for(int i=0; i<n; i++)
s[i] = new String(res[i]);
list.add(s);
}
for(int i=0; i<n; i++) {
if(cols[i] != 1 && slash1[cur + i] != 1 && slash2[n-1-cur+i] != 1) {
cols[i] = 1;
slash1[cur + i] = 1;
slash2[n-1-cur+i] = 1;
res[cur][i] = 'Q';
DFS(res, n, cur+1, cols, slash1, slash2);
cols[i] = 0;
slash1[cur + i] = 0;
slash2[n-1-cur+i] = 0;
res[cur][i] = '.';
}
}
}
}
I didn't invent a wheel here. We just remember the busy columns and diagonals and recursively try to put the queen into the next row. But I think the code below is short enough to be reproduced in the interview.
Hope it helps!
public class Solution { private void helper(int r, boolean[] cols, boolean[] d1, boolean[] d2, String[] board, List<String[]> res) { if (r == board.length) res.add(board.clone()); else { for (int c = 0; c < board.length; c++) { int id1 = r - c + board.length, id2 = 2*board.length - r - c - 1; if (!cols[c] && !d1[id1] && !d2[id2]) { char[] row = new char[board.length]; Arrays.fill(row, '.'); row[c] = 'Q'; board[r] = new String(row); cols[c] = true; d1[id1] = true; d2[id2] = true; helper(r+1, cols, d1, d2, board, res); cols[c] = false; d1[id1] = false; d2[id2] = false; } } } } public List<String[]> solveNQueens(int n) { List<String[]> res = new ArrayList<>(); helper(0, new boolean[n], new boolean[2*n], new boolean[2*n], new String[n], res); return res; } }