赞
踩
参照LeetCode第51题的题干,N皇后是指将N个皇后放置在NXN的棋盘上,并且皇后之间不可以互相攻击,即其中任意两个皇后不能在同一行、同一列或者同一条斜线上。
四皇后的放置情况示例如下:
采用回溯法解决该问题时需要将搜索过程抽象成一颗树,只要搜索到达了树的叶子节点,则等于找到了所有皇后合理的放置位置。
其中三皇后问题的解决思路如下,注意三皇后是无解的:
将整个棋盘抽象为坐标轴,按照从上到下的顺序放置皇后,每一行放置一个后即可进行下一行的放置,过程如图:
对应的Java代码如下:
- //输入棋盘边长n,返回所有合法的放置位置
- public List<List<String>> solveNQueens(int n)
- {
- //题目要求使用二维字符串数组返回
- List<List<String>> res = new ArrayList<>();
- LinkedList<List<String>> board = new LinkedList<>();
- backtrack(res,board,0,n);
- return res;
- }
-
- //按照题目要求初始化每行
- public List<String> initList(int n)
- {
- List<String> temp = new ArrayList<>();
- for(int j=0;j<n;j++)
- {
- temp.add(".");
- }
- return temp;
- }
-
- //处理返回结果为题目要求的样式
- public List<String> convertBoard(LinkedList<List<String>> board)
- {
- List<String> res = new ArrayList<>();
- for(int i=0;i<board.size();++i)
- {
- String temp = String.join("",board.get(i));
- res.add(temp);
- }
- return res;
- }
-
- //回溯方法
- public void backtrack(List<List<String>> res,LinkedList<List<String>> board,int y,int n)
- {
- if(board.size()>=n||y>=n)
- {
- res.add(convertBoard(board));
- return;
- }
- for(int i=0;i<n;++i)
- {
- //假如当前位置不合法,剪枝
- if(!isValid(board,i,y,n))
- continue;
- //当前位置可以放置
- List<String> yList = initList(n);
- yList.set(i,"Q");
- board.add(yList);
- //处理下一行
- backtrack(res,board,y+1,n);
- //取消选择
- board.removeLast();
- }
- }
-
- public boolean isValid(LinkedList<List<String>> board,int x,int y,int n)
- {
- //检查上方是否有冲突
- for(int i=0;i<y;++i)
- {
- if(board.get(i).get(x).equals("Q"))
- return false;
- }
- //检查右上方是否有冲突
- for(int i=x+1,j=y-1;i<n&&j>=0;i++,j--)
- {
- if(board.get(j).get(i).equals("Q"))
- return false;
- }
- //检查左上方是否有冲突
- for(int i=x-1,j=y-1;i>=0&&j>=0;i--,j--)
- {
- if(board.get(j).get(i).equals("Q"))
- return false;
- }
- return true;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。