N皇后
51. N皇后
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。
示例:
输入: 4
输出: [
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
1 public class T51 { 2 public List<List<String>> solveNQueens(int n) { 3 4 List<List<String>> lists = new ArrayList<>(); 5 HashSet<Integer> c_set = new HashSet<>(); 6 HashSet<Integer> pos_set = new HashSet<>(); 7 HashSet<Integer> neg_set = new HashSet<>(); 8 9 backtracking(0, n, lists, new ArrayList<String>(), c_set, pos_set, neg_set); 10 11 return lists; 12 } 13 14 private void backtracking(int i, int n, 15 List<List<String>> lists, ArrayList<String> strList, 16 HashSet<Integer> c_set, HashSet<Integer> pos_set, HashSet<Integer> neg_set) { 17 if (i == n) { 18 lists.add(new ArrayList<>(strList)); 19 return; 20 } 21 for (int j = 0; j < n; j++) { 22 if (!c_set.contains(j) && !pos_set.contains(i + j) && !neg_set.contains(i - j)) { 23 c_set.add(j); 24 pos_set.add(i + j); 25 neg_set.add(i - j); 26 char[] chars = new char[n]; 27 Arrays.fill(chars, '.'); 28 chars[j] = 'Q'; 29 strList.add(new String(chars)); 30 backtracking(i + 1, n, lists, strList, c_set, pos_set, neg_set); 31 strList.remove(strList.size() - 1); 32 c_set.remove(j); 33 pos_set.remove(i + j); 34 neg_set.remove(i - j); 35 } 36 } 37 38 } 39 }
52. N皇后 II
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回 n 皇后不同的解决方案的数量。
示例:
输入: 4
输出: 2
解释: 4 皇后问题存在如下两个不同的解法。
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
1 public class T52 { 2 int res; 3 public int totalNQueens(int n) { 4 //列、正斜率斜线、负斜率斜线 5 HashSet<Integer> cSet = new HashSet<>(); 6 HashSet<Integer> posSet = new HashSet<>(); 7 HashSet<Integer> negSet = new HashSet<>(); 8 9 backtracking(0, n, cSet, posSet, negSet); 10 return res; 11 12 } 13 14 private boolean backtracking(int i, int n, HashSet<Integer> cSet, HashSet<Integer> posSet, HashSet<Integer> negSet) { 15 if (i == n) { 16 return true; 17 } 18 for (int j = 0; j < n; j++) { 19 if (!cSet.contains(j) && !posSet.contains(i + j) && !negSet.contains(i - j)) { 20 cSet.add(j); 21 posSet.add(i + j); 22 negSet.add(i - j); 23 if (backtracking(i + 1,n,cSet,posSet,negSet)) res += 1; 24 cSet.remove(j); 25 posSet.remove(i + j); 26 negSet.remove(i - j); 27 } 28 } 29 return false; 30 } 31 }
一回生,二回熟