52. N皇后 II

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

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

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

示例:

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

 ["..Q.",  // 解法 2
  "Q...",
  "...Q",
  ".Q.."]
]

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


package leetCode5_26;

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

/**
 * @author : caoguotao
 * @date 创建时间:2019年5月31日 下午10:09:03
 * @version 1.0
 * @parameter
 * @since
 * @return
 */
public class Solution52 {
	// 列、左对角线、右对角线
	boolean[] cols, diagLF, diagRT;

	public static void main(String[] args) {
		Solution52 s = new Solution52();
		int res = s.totalNQueens(4);
		System.out.println(res);
	}

	/**
	 * 解题思路: 
	 * 	采用三个数组分别记录每列、左对角线、右对角线是否有皇后
	 *  	然后递归的遍历所有的左边位置
	 */
	public int totalNQueens(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 0;
		}
		// 用来保存棋盘
		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.size();
	}

	/**
	 * 
	 * @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、付费专栏及课程。

余额充值