1 .概要
回溯算法实际上是一个类似枚举的搜索尝试过程,主要是在搜索尝试的过程中寻找问题的解,如果发现不满足求解条件,则“回溯”返回尝试另一条路径。 回溯法是一种选优搜索法,为了达成目标,在选优条件下向前搜索。 但是,在探索了某一步的时候,如果原来的选择不优秀或者没有达到目标,就返回一步重新选择。 这样,如果不顺利就返回的技术是回溯法,将满足有回溯条件的状态的点称为“回溯点”。 许多复杂、规模大的问题都使用回溯法,有“通用求解方法”的美称。
2 .原理
通过皇后问题说明回溯算法。
回溯算法经典案例皇后问题:
n-quean问题研究的是如何在nn的棋盘上放置n个quean,并且quean之间不能互相攻击。
给定整数n,返回所有不同的n皇后问题的解决方案。
每种解法都包含明确的n皇后问题棋子的放置方法,在该方案中,' q '和'.' 分别表示皇后和空位。
示例:输入: 4
//解法1 //解法2
: 4解释皇后问题有两种不同的解法。
回溯算法原理图:
如何判断皇后是否会受到攻击:横排,竖排判断,对角线如何判断
根据图解找出对角线定律。
3代码:
importjava.util.ArrayList; importjava.util.List; public classSubject98 {//竖写被注册,用于判断能否受到竖写攻击
int rows[]; //
//在“从左到右的对角线”上登录,用于判断是否会受到纵列攻击
inthills[]; //在“从右到左的对角线”上登录,用于判断是否受到纵列攻击
intdales[]; intn; //output
List output=newArrayList (; //皇后的位置
intqueens[]; publicstaticvoidmain (string [ ] args ) {
listlistlist=newsubject 98 (.solvenqueens ) 6;
system.out.println(listlist;
(}/***判断该位置是否受到攻击
*@paramrow
*@paramcol
*@return
*/
publicbooleanisnotunderattack (introw,intcol ) ) intres=rows [ col ] hills [ row-coln-1 ] dales [ row col ]; 返回(RES==0)? 真:假;
(}/***让皇后进入这个位置
*@paramrow
*@paramcol*/
publicvoidplacequeen(introw,intcol ) {
queens[row]=col; //放入皇后的位置
rows[col]=1; //纵向排列攻击位置
hills[row - col n - 1]=1; //“从左到右对角线”攻击位置
dales[row col]=1; //“从右到左的对角线”攻击位置
(}/***后皇后位置
*@paramrow
*@paramcol*/
publicvoidremovequeen(introw,intcol ) {
queens[row]=0;
rows[col]=0;
hills[row- col n - 1]=0;
dales[row col]=0;
}/***将满足条件的皇后位置放入output
公共视频解决方案
List solution=new ArrayList (; for(intI=0; i n; I({intcol=queens[I];
stringbuilder sb=new stringbuilder (; for(intj=0; j col; j ) sb.append ('.' );
sb.append('q ); for(intj=0; j n - col - 1; j ) sb.append ('.' );
solution.add(sb.tostring ) );
}
output.add(solution;
}publicvoidbacktrack(introw ) ) for ) intcol=0; col n; col () if ) isnotunderattack(row,col ) )。
placequeen(row,col ); //皇后的数量是否满足,如果满足则输出
if(row1==n ) addSolution ); //如果不满意就继续
ELSEbacktrack(row1; //追溯到。
removequeen(row,col );
}
}
}publiclistSolvenqueens(intn ) ) {this.n=n;
rows=new int[n];
hills=new int[2 * n - 1];
dales=new int[2 * n - 1];
queens=new int[n];
回退(0; 返回输出;
}
}