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;}
}