视频讲解
八皇后问题
1.同一列不能碰撞
- 同一列不能碰撞
- 对角线不能碰撞 斜线
- 反斜线
回溯算法
基础的代码,每一列来处理即可,其中入口是第一列到第八列,每一列中的循环有八个位置可以选择,判断每个位置是否可以选择,
主程序的基础结构
- dfs(结果存储res, 开始列表, 开始列 ==0)
dfs设计(深度优先遍历设计)
如果到达最后一列(满足题意的一个回溯)
res.add(重构函数(二维数组))
for(每一列的大小要判断下,共有多少情况选择)
{
if(判断位置是否能够放置)
{
1 该位置放一个皇后,
深入到下面一个一列(列数+1)
2 回退操作,(该位置放一个非皇后)
(回溯算法中1和2的连个逻辑关系是一样的)
}
函数是否能够放得下(遍历前面的位置)
如果某个位置满足是一个皇后,并且满足下面三种情况下的一种即可
1. 在同一个对角线上 i+x = j+y
2. 在同一列上 j = y,
3. 在反对角巷上 i+j =x+y,
其中i, j 代表要遍历的元素,x和y代表要判断的位置,即时是深度优先搜索到的位置
重构函数
构造一个满足题意的二位数组,该数组记录着正确的执行情况
##代码(Java)
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class N_Queues {
/**
* 八皇后问题,每一行一个字符,相邻两行的字符不能相接触,不能在一条斜线上和对角线上,同时不能在同一列
* @param n
* @return
*/
public List<List<String>> solution(int n){
char[][] board = new char[n][n];
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
board[i][j] = '.';
}
}
List<List<String>> res = new ArrayList<>();
dfs(board,0,res);
//正常的回溯算法,一个结果状态res,,回溯起始位置0(第一列),回溯的结果表board
return res;
}
//i代表处理的列,i在这里表示的处理开始起始位置,从第一列开始到第八列,
private void dfs(char[][] board, int colunm_index, List<List<String>> res) {
//回溯的结束条件,添加结果列表,如果不能达到最后一列结果时,则不会时满足题意的条件,不会发生添加这种情况
if (colunm_index == board.length) {
res.add(constructor(board));
return;
}
//每一列回溯有八个可选择的,所有for 循环为八重关系
for (int i = 0; i < board.length; ++i) {
if (validate(board, i, colunm_index)) {
//for循环里面三部曲,
//如果该位置可以放置一个皇后,继续下一列,加入操纵
board[i][colunm_index] = 'Q'; // 类似于 subset 中的 tmp.pu(i),
//深入下去
dfs(board, colunm_index + 1, res);
//回退操作,
board[i][colunm_index] = '.'; // tempList.remove
/* tempList.add(nums[i]);
backtrack(list, tempList, nums, i + 1);
/*清空所有的路径中的内容*/
// tempList.remove(tempList.size() - 1);
// */
}
}
}
private boolean validate(char[][] board, int x,int y){
for(int i=0;i<board.length;i++){
for(int j=0;j<y;++j){
//如何判断在同一条对角线上的元素 board[i][j] = 'Q' && x+i = y+j(对角线上的元素), x+y=i+j(是斜对角线上的情况),
if(board[i][j]=='Q' && (x+j==y+i) ||x+y==i+j||x==i)
return false;
}
}
return true;
}
private List<String> constructor(char[][]board){
//重新构造每一列的情况
//board[i]代表以为以为数组中的一个数组
List<String> res = new LinkedList<>();
for(int i=0;i<board.length;i++){
String s= new String(board[i]);
//使用一个char[]来新建一个string也是可以的
res.add(s);
}
return res;
}
public static void main(String[] args) {
char bord[][] = {{'0', '1', '0', '1'},
{'1', '0', '0', '1'},
{'1', '0', '0', '1'},
{'1', '0', '0', '1'}};
//
List<String> res = new LinkedList<>();
for (int i = 0; i < bord.length; ++i) {
String s = new String(bord[i]);
res.add(s);
}
for (String s :res) System.out.println(s);
char b[] = {'1','2'};
//使用一个char[] 构造一个字符串
String s =new String(b);
System.out.println(s);
}
}