LeetCode 51 N皇后

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

在这里插入图片描述
上图为 8 皇后问题的一种解法。

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

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

思路

经典问题。类似 数独、八皇后等类似问题,都可以使用回溯法解决。此题使用回溯法解题,对8个皇后进行循环摆放,每摆放好一个就对整个棋盘进行一次验证是否存在攻击。当新摆放的皇后出现攻击现象时,则进行回溯至前一个皇后,对其重新进行摆放。
使用一个一维数组来表示n个皇后位置 ,下标表示是第几个皇后,对应元素值表示该皇后选择的第几个位置。

int[] x=new int[n];

验证皇后j和j之间是否合法方法:

皇后之间出现攻击主要三种 :

  1. 同一列(一个皇后占一列,每个皇后从它自己的列中选择一行)
i==j
  1. 同一列
x[i]==x[j]
  1. 同一对角线
Math.abs(x[i]-x[j])=Math.abs(i-j)

每次第k个皇后选好位置之后,都要将 0 ~ k-1 个皇后和第k个皇后进行一一对比。

代码

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

public class N_Queens_51 {
    /**
     * @return java.util.List>
     * @author chy
     * @creed: Talk is cheap,show me the code
     * @date 18/5/2019 11:28 AM
     * @desc: 51 上图为 8 皇后问题的一种解法。
     * 

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

* 每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。 */ public List> solveNQueens(int n) { int[] x = new int[n + 1]; List> results = new ArrayList<>(); int k = 1;//从第一个皇后开始进行选择 while (k > 0) { x[k] += 1;//首先先初始化第k个皇后所选择的行(有两种情况,第一个是前一个皇后选好了,则这个皇后初始化为1,另外一种情况就是后面第k+1个皇后摆放失败,回溯回来,则将选择下一行) while (x[k] <= n && !verify(x, k))//x[k]<=n表示选择还是有选择的,若x[k]>n了则表示第k个皇后摆放失败 x[k] += 1; if (x[k] <= n) { if (k == n)//表示n个皇后都已摆放完成,则输出结果矩阵 { results.add(array2list(x, n)); } else { k++; x[k] = 0; } } else //表示摆放失败 进行回溯 k--; } return results; } /* * 验证第k个皇后与前面k-1个是否有冲突 * */ public boolean verify(int[] x, int k) { for (int i = 1; i < k; i++) { if (x[i] == x[k] || Math.abs(x[i] - x[k]) == Math.abs(i - k)) return false; } return true; } /* * 将用来计数的一维数组转化为列表 * */ public List array2list(int[] x, int n) { List res = new ArrayList<>(); for (int i = 1; i <= n; i++) { String temp = ""; for (int j = 1; j <= n; j++) { if (x[i] == j) temp += 'Q'; else temp += '.'; } res.add(temp); } return res; } public static void main(String[] argc) { List> e = new N_Queens_51().solveNQueens(4); for (List i : e) { for (String item : i) System.out.println(item); System.out.println(); } } }

你可能感兴趣的:(LeetCode每日一题)