您的位置:首页 > 产品设计 > UI/UE

leetcode n-queens

2016-05-08 19:30 316 查看
N皇后是一个十分经典的问题。

这题一个经典的解法就是回溯法。

一开始使用回溯法的话。陷入了两个误区。

第一,每次回溯都从第一个点开始计算,其实完全没必要。

第二,每次回溯都将当前解空间复制一遍。其实也没有必要。

上网搜了一下解法。核心思想为,因为N皇后问题限制每行只能放一个皇后。所以,考虑以行为维度考虑问题而不是以

点为维度考虑问题。

对于每次递归,检索当前行内所有的点,如果找到一个点就进入下一行。如果当前行所有点都无效,则直接返回。

那么对于解空间的问题。一开始觉得每次分裂出一个新的解,就需要把其上一行的解空间复制一遍,以保证其没有冲突。

其实没有必要这么做,回溯法一个重要的点就是,从头到尾只使用一个解空间,只是当你完成某个维度的检索,返回上一级

维度时,将当前维度的解空间清空即可。这一点在上一个博文permuations中也有体现,他在完成一个维度的检索之后,

再把交换过的元素交换回来。

下面给出代码

import java.util.ArrayList;
import java.util.List;

public class Solution2 {

/**
* @param args
*/
public List<List<String>> solveNQueens(int n) {

ArrayList<List<String>> result=new ArrayList<List<String>>();
int [][]nums=new int

;
f(0,0,nums,result);
return result;

}
private void f(int x,int y,int[][] nums, ArrayList<List<String>> result)
{

//p(nums);
// System.out.println("--------------");

for(int i=0;i<nums.length;i++)
{

if(test(nums,x,i))
{
nums[x][i]=1;
if(x==nums.length-1)
{
result.add(Convert(nums));
break;
}

f(x+1,0,nums,result);
}
nums[x][i]=0;

}

for(int i=0;i<nums.length;i++)
nums[x][i]=0;
}

private boolean test(int [][]solution,int x,int y)
{

for(int i=0;i<solution.length;i++)
for(int j=0;j<solution[i].length;j++)
{
if(solution[i][j]==1)
{
if(x==i||y==j)
return false;
double gradient=(double)(y-j)/(double)(x-i);

if(gradient==1.0||gradient==-1.0)
return false;
}
}
return true;

}
private ArrayList<String> Convert(int [][]solution)
{
ArrayList<String> result=new ArrayList<String>();
for(int i=0;i<solution.length;i++)
{
String tmp="";
for(int j=0;j<solution[i].length;j++)
{
if(solution[i][j]==0)
tmp+=".";
else
tmp+="Q";
}
result.add(tmp);

}
return result;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: