NQueens, NQueens2 N皇后问题,递归回溯

N皇后的规则:任意两个皇后不在同一行,不在同一列,不在同一斜线上。

算法分析:这种问题就用回溯法。深度搜索然后回溯。用一个数组记录每一行皇后的位置,下标代表行,值代表列。对行深度搜索。

public class NQueens 
{
	public List<List<String>> solveNQueens(int n)
	{
		List<List<String>> res = new ArrayList<>();
		if(n <= 0)
		{
			return res;
		}
		int[] columnVal = new int[n];
		DFS_helper(n, res, 0, columnVal);
		return res;
	}
	
	public void DFS_helper(int queensNum, List<List<String>> res, int row, int[] columnVal)
	{
		if(row == queensNum)//已经遍历所有行了,得到结果
		{
			List<String> list = new ArrayList<>();
			for(int i = 0; i < queensNum; i ++)
			{
				StringBuffer sb = new StringBuffer();
				for(int j = 0; j < queensNum; j ++)
				{
					if(j == columnVal[i])
					{
						sb.append("Q");
					}
					else
					{
						sb.append(".");
					}
				}
				list.add(sb.toString());
			}
			res.add(list);
		}
		else
		{
			for(int i = 0; i < queensNum; i ++)
			{
				columnVal[row] = i;
				if(isValid(row, columnVal))//合法,就寻找下一行的位置,否则,变换当前行的值
				{
					DFS_helper(queensNum, res, row+1, columnVal);
				}
			}
		}
	}
	
	public boolean isValid(int row, int[] columnVal)
	{
		for(int i = 0; i < row; i ++)
		{
			if(columnVal[i] == columnVal[row] || Math.abs(columnVal[row] - columnVal[i])== row - i)
			{
				return false;
			}
		}
		return true;
	}
	
	public static void main(String[] args)
	{
		NQueens q = new NQueens();
		List<List<String>> list = q.solveNQueens(8);
		Iterator<List<String>> it = list.iterator();
		int count = 0;
		while(it.hasNext())
		{
			System.out.println(it.next());
			count ++;
		}
		System.out.println(count);
	}
}

NQueens2:计算有多少种解决方案。

算法分析:用一个成员变量来记录解决方案的个数。

public class Nqueens2 {
	public int count;
	public int totalNQueens(int n)
	{
		count = 0;
		if(n <= 0)
		{
			return count;
		}
		int[] columnVal = new int[n];
		DFS_helper(n, 0, columnVal);
		return count;
	}
	
	public void DFS_helper(int queensNum, int row, int[] columnVal)
	{
		if(row == queensNum)//已经遍历所有行了,得到结果
		{
			count ++;
		}
		else
		{
			for(int i = 0; i < queensNum; i ++)
			{
				columnVal[row] = i;
				if(isValid(row, columnVal))//合法,就寻找下一行的位置,否则,变换当前行的值
				{
					DFS_helper(queensNum, row+1, columnVal);
				}
			}
		}
	}
	
	public boolean isValid(int row, int[] columnVal)
	{
		for(int i = 0; i < row; i ++)
		{
			if(columnVal[i] == columnVal[row] || Math.abs(columnVal[row] - columnVal[i])== row - i)
			{
				return false;
			}
		}
		return true;
	}
}
原文地址:https://www.cnblogs.com/masterlibin/p/5760847.html