51. N皇后

皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

上图为 8 皇后问题的一种解法。

给定一个整数 n,返回所有不同的 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

示例:

输入: 4
输出: [
 [".Q..",  // 解法 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。

解题思路:
     *         采用三个数组分别记录每列、左对角线、右对角线是否有皇后
     *         然后递归的遍历所有的坐标位置


package leetCode5_26;

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

/** 
* @author : caoguotao
* @date 创建时间:2019年5月31日 下午8:58:25 
* @version 1.0 
* @parameter  
* @since  
* @return  
*/
public class Solution51 {
	//列、左对角线、右对角线
	boolean[] cols, diagLF, diagRT;
	public static void main(String[] args) {
		Solution51 s = new Solution51();
		List<List<String>> lists = s.solveNQueens(4);
		for (List<String> list : lists) {
			for (String list2 : list) {
				System.out.println(list2);
			}
			System.out.println("\n");
		}

	}
	/**
	 * 	解题思路:
	 * 		采用三个数组分别记录每列、左对角线、右对角线是否有皇后
	 * 		然后递归的遍历所有的左边位置
	 */		
	 public List<List<String>> solveNQueens(int n) {
		 cols = new boolean[n];
		 diagLF = new boolean[2 * n - 1];
		 diagRT = new boolean[2 * n - 1];
		 //保存所有的结果
		 List<List<String>> lists = new ArrayList<List<String>>();
		 if(n == 0) {
			 return lists;
		 }
		 //用来保存棋盘
		 char[][] boards = new char[n][n];
		 //初始化棋盘
		 for(int i = 0; i < n; i++) {
			 for(int j = 0; j < n; j++) {
				 boards[i][j] = '.';
			 }
		 }
		
		DFS(0, 0, n, boards, lists);
		return lists;     
	 }
	 /**
	  * 
	  * @param r 行号
	  * @param i 列号
	  * @param n 皇后总个数
	  * @param boards 棋盘
	  * @param lists 所有可能的棋盘
	  */
	public void DFS(int r, int c, int n, char[][] boards, 
			List<List<String>> lists) {
		//得到一种可能
		if(r == n) {
			List<String> l = new ArrayList<String>();
			for(int i = 0; i < n; i++) {
				String s = "";
				for(int j = 0; j < n; j++) {
					s += boards[i][j];
				}
				l.add(s);
			}
			lists.add(l);
			return;
		}
		for(int col = c; col < n; col++) {
			//根据行、列计算所处的左对角线和右对角线的行数
			if(cols[col] || diagLF[col + r] || diagRT[n - col + r - 1]) {
				continue;
			}
			//放置皇后
			boards[r][col]= 'Q';
			//将对应位置的列、左对角线、右对角线修改为true
			updateCLR(r, col, n, true);
			DFS(r + 1 , 0, n, boards, lists);
			//不放置皇后
			boards[r][col] = '.';
			updateCLR(r, col, n, false);
		}
		
	}
	/**
	 * 
	 * @param r 行号
	 * @param col 列号
	 * @param n 皇后数
	 * @param b 修改值
	 */
	public void updateCLR(int r, int col, int n, boolean b) {
		cols[col] = b;
		diagLF[col + r] = b;
		diagRT[n - col + r - 1] = b;
	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值