N皇后问题
来源:互联网 发布:spss软件应用例子 编辑:程序博客网 时间:2024/04/30 12:28
原题 https://oj.leetcode.com/problems/n-queens/
这个题写了好久。。。
其实思路比较简单。在每一列上按顺序每一个位置放皇后,而前面已经放好的皇后位置对后面放的皇后的位置是有影响的,因此以后选择摆放位置时要遵守前面的约束。
流程基本是:先在第一列选择一个位置放皇后,然后在第二列选择位置时不能和第一列的皇后有冲突(在一条直线或对角线上),在第三列时不能与一二列有冲突,以此类推,直到找到最后一列符合条件的位置,结果记录下来,然后回溯找其他符合条件的位置;或者在第i列时发现没有任何一个位置符合条件,于是需要回溯到第i-1列去,在该列上换下一个位置,继续以上流程。
整个流程类似于深度优先搜索。用栈保存访问过的位置信息,实现回溯。
import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Stack;public class Solution { private final char INIT = '#'; public static void main(String[] a) { for(String[]ss :new Solution().solveNQueens(5)) { for(String s : ss) System.out.println(s); System.out.println(); } } public List<String[]> solveNQueens(int n) { List<String[]> ll = new LinkedList<String[]>(); char[][][] charsOnStep = new char[n+1][n][n]; charsOnStep[0] = this.getChars(n); int pre = -1;//上一步是第几步 Stack<int[]> steps = new Stack<int[]>();//用行,列值对来表示步骤 steps.push(new int[]{0,0}); pre = -1; charsOnStep[1] = this.putQ(0, 0, charsOnStep[0]); while(!steps.isEmpty()) { int[] head = steps.peek(); int r,c; if(pre >= head[1])//回溯 { r = head[0]+1;//回溯时,要接着上次访问的行数+1的位置 c = head[1]; steps.pop(); } else { r = 0; c = head[1]+1; } int i =c; for(;i<n; i++)//列 { boolean found = false; pre = i; for(int j = r;j<n; j++)//行 { char[][] temp = charsOnStep[i]; if(temp[j][i] == '#') { charsOnStep[i+1] = putQ(j,i,temp); steps.push(new int[]{j,i}); found = true; r = 0;//这里需要把r重置为0,使下一列继续从0开始扫描 break; } } if(!found)//没找到,说明走到i列时不能走下去了,需要回溯 { break; } } if(i == n)//已经走到最后了,记录结果,然后该回溯了 { pre = i; ll.add(ctoss(charsOnStep[n])); } } return ll; } //用一个二维的字符数组构造字符串数组 private String[] ctoss(char[][] cs) { String[] re = new String[cs.length]; for(int i = 0;i<cs.length; i++) re[i] = new String(cs[i]); return re; } //在r行c列上放置Q,并依据此Q的位置更新其直线斜线上的点为'.' public char[][] putQ(int r, int c, char[][] cs) { cs = copy(cs); cs[r][c] = 'Q'; for(int i = 0;i<cs.length; i++) if(i != r) cs[i][c] = '.'; for(int i = 1;i < cs.length-c;i++) { cs[r][c+i] = '.'; if(r+i < cs.length) cs[r+i][c+i] = '.'; if(r-i >= 0) cs[r-i][c+i] = '.'; } return cs; } public char[][] copy(char[][] cs) { char[][] c = new char[cs.length][cs.length]; for(int i = 0;i<cs.length; i++) for(int j = 0;j<cs.length; j++) c[i][j] = cs[i][j]; return c; } //初始化一个字符的二维数组,初始值用#标记 public char[][] getChars(int n) { char[][] cs = new char[n][n]; for(int i = 0;i<n; i++) for(int j = 0;j<n; j++) cs[i][j] = INIT; return cs; }}
0 0
- N*N皇后问题
- 八皇后 n皇后 问题
- 八皇后N皇后问题
- N皇后问题
- n皇后问题
- N皇后问题
- N 皇后问题
- N皇后问题
- N皇后问题算法
- N 皇后问题
- N皇后问题
- N皇后问题
- n皇后问题
- N皇后问题
- N皇后问题优化
- N皇后问题
- n皇后问题
- N皇后问题
- 解剖Nginx·自动脚本篇(6)编译器名称变量脚本 auto/cc/name
- 2014-10-25Android学习--------SimpleAdapter的实现
- 网站缓存
- Nearest Common Ancestors Poj1330
- 用户识别
- N皇后问题
- 让需求活动脚踏实地(零)——搞需求太难了
- CocosEditor-java
- eclipse各版本说明与区别
- C++中的private、protected、public区别
- 常用的sql语句小结
- c语言学习的阶段性小总结
- 向全世界发出第一篇博客
- ORACLE 多表关联 UPDATE 语句