有名的N-QUEEN问题,上学的时候作为例题来讲back track。
对于这种问题,我有一个独特的小窍门,我称之为楞算法,或者生算法。英文叫做brute force.....
这个题就是backtrack,而且backtrack的情况只有一个,就是俩皇后争风吃醋,要弄死对方。每放置一个皇后,都要看看横竖斜的情况。
我使用的code ganker一维数组检测的方式。
function(int[] dp, int row)
{
for(int i = 0; i < row;i++)
{
if(dp[i] == row) false; //和前面某一列的上的Q占用了同一行。
if(Math.abs(i-row) == Math.abs(dp[i] - dp[row])) false
// 第二个是检测鞋方向的。假如斜方向有2个Q,那么他们组成
// 的直线,如果放在平面直角坐标系里,斜率是1。斜率就是
// Y的差/X的差,用一个取绝对值,这样如果斜率是1,也就是
// 他俩相等,证明在斜线上。
}
}
dp[i]表示的是第i列的Q放在第几行。因为肯定不能放在同一列,按理说应该是二维数组,dp[i][j],迭代过去是dp[i][j+1],这里我们没那个必要。。
public class Solution
{
public List<List<String>> solveNQueens(int n)
{
List<List<String>> res = new ArrayList<List<String>>();
int[] dp = new int[n];
helper(res,dp,0,n);
return res;
}
public void helper(List<List<String>> res, int[] dp, int m, int n)
{
if(m == n)
{
List<String> tempList = new ArrayList<String>();
for(int i = 0; i < dp.length;i++)
{
String tempStr = "";
for(int j = 0; j < n;j++)
{
if(dp[i] == j) tempStr += "Q";
else tempStr += ".";
}
tempList.add(tempStr);
}
res.add(tempList);
}
else
{
for(int i = 0; i < n; i++)
{
dp[m] = i;
if(ok(dp,m))
{
helper(res,dp,m+1,n);
}
}
}
}
public boolean ok(int[] dp,int m)
{
for(int i = 0; i < m;i++)
{
if(dp[i] == dp[m]) return false;
if(Math.abs(m-i) == Math.abs(dp[m]-dp[i])) return false;
}
return true;
}
}