经典的回溯算法问题
我们需要想清楚2点
- 需要使用回溯算法
- 如何判断两个皇后是否可以相互攻击
回溯算法就不需要多说了。判断2个皇后是否可以相互攻击,主要看是否是同一行,同一列,或者同一对角线的。我们可以开额外的空间存储存储同列的,同行的,同对角线的坐标,同对角线的怎么把他们用一个确定的数字表示呢?我们可以把他们分为2类
- 从右下角到左上角,也就是斜率为-1
这条线上的坐标均有 x+y = k(常数),k为直线与y轴的截距 - 从左下角到右上角也就是斜率为1
这条线上的坐标均有 x-y = k,k为直线与x轴的截距
code:
package undone;
import com.sun.rowset.internal.Row;
import java.util.*;
/**
* @desc
* 经典回溯算法:n皇后问题
*/
public class t51 {
class Position {
Position(int x, int y) {
this.x = x;
this.y = y;
}
int x;
int y;
}
List<List<Position>> posList = null;
Set<Integer> RowSet = new HashSet<>();
Set<Integer> ColSet = new HashSet<>();
Set<Integer> AsLeft = new HashSet<>();
Set<Integer> AsRight = new HashSet<>();
public List<List<String>> solveNQueens(int n) {
if(n == 0) {
return new ArrayList<>();
}
posList = new ArrayList<>();
solveNQueens(new ArrayList(), 0, n);
return generatorResult(posList, n);
}
public void solveNQueens(List<Position> poses, int row, int n) {
if(n == poses.size()) {
List<Position> list = new ArrayList();
list.addAll(poses);
posList.add(list);
}
for(int i = row; i < n; i++) {
for (int j = 0; j < n; j++) {
if(judge(i, j)) {
poses.add(new Position(i, j));
RowSet.add(i);
ColSet.add(j);
AsLeft.add(i+j);
AsRight.add(i-j);
solveNQueens(poses, i+1, n);
poses.remove(poses.remove(poses.size() - 1));
RowSet.remove(i);
ColSet.remove(j);
AsLeft.remove(i+j);
AsRight.remove(i-j);
}
}
}
}
public String getString(int j, int n) {
char[] cs = new char[n];
for(int i = 0; i < n; i++) {
if(i == j) {
cs[i] = 'Q';
continue;
}
cs[i] = '.';
}
return new String(cs);
}
public List<List<String>> generatorResult(List<List<Position>> lists, int n) {
List<List<String>> result = new ArrayList<>();
for (List<Position> list : lists) {
List<String> item = new ArrayList<>();
for (Position position : list) {
item.add(getString(position.y, n));
}
result.add(item);
}
return result;
}
public boolean judge(int x0, int y0) {
return !(RowSet.contains(x0) || ColSet.contains(y0) || AsLeft.contains(x0 + y0) || AsRight.contains(x0 - y0));
}
/**
* Main方法
* @param args
*/
public static void main(String[] args) {
t51 t51 = new t51();
System.out.println(t51.solveNQueens(4));
}
}