N-queue

问题描述

  1. leetcode N 皇后问题。要求在 N*N 的方格中放入皇后  'Q' ,要求皇后之间上下左右、斜对角均不能相互攻击。
  2. 也就是皇后之间出现的位置是有限制的。同一行、列、斜线上只能出现一个皇后,且每一行必有一个皇后。
  3. 给定 N,求出所有的不重复的解集。返回值类型为 List<List<String>>

解决思路

  1. 又是 N*N 的方格,需要对每个位置进行皇后的填充,自然想到利用 DFS 进行处理。
  2. 在当前位置进行判断是否可以填入皇后时,需要判断该列、该位置所在的左斜线、右斜线上是否还有其他的皇后,有则跳过,无则添加。leetcode 官方题解上给出了一种巧妙的判断斜线上是否有皇后的方法,对于左斜线,可以看成是一条直线:x+y = Constant。 抓住横坐标 + 纵坐标的和为常数这个特点,就可以很好的进行判断了,右斜线同样如此。
  3. 先将所有的皇后所在的下标索引找出来,最后再根据每一个下标索引生成字符串。如在 N = 4 的时候,先求出这样的结果:list:[ [1302], [2031] ] 。 

代码

 1 public class Solution {
 2 
 3     private static Set<Integer> col = new HashSet<>();
 4     private static Set<Integer> pie = new HashSet<>();
 5     private static Set<Integer> na = new HashSet<>();
 6 
 7     public static List<List<String>> solveNQueens(int n) {
 8         List<List<String>> res = new ArrayList<>();
 9         List<List<Integer>> temp = new ArrayList<>();
10 
11         DFS(n, 0, new ArrayList<>(), temp);
12         for (List<Integer> a: temp) {
13             for(int b: a) {
14                 char[] curChar = new char[n];
15                 Arrays.fill(curChar,'.');
16                 curChar[b] = 'Q';
17                 cur.add(new String(curChar));
18             }
19             res.add(cur);
20         }
21 
22         return res;
23 
24     }
25 
26     public static void DFS(int n, int row, ArrayList<Integer> curRes, List<List<Integer>> res) {
27         // 递归终止条件
28         if (row >= n) {
29             // res.add(curRes); 注意这里如果不重新声明一个ArrayList的话,后面获取的         
30             //ArrayList会将之前的结果覆盖。
31 
32             res.add(new ArrayList<>(curRes));
33 
34             //  System.out.println("=====下面是DFS中的res遍历====");
35             // for(List a: res) {
36             //    for(int i=0; i< a.size(); i++) {
37             //        System.out.print(a.get(i));
38             //    }
39             //   System.out.println();
40             // }
41             // System.out.println("--------------------");
42 
43             return;
44         }
45 
46         for(int i=0; i<n; i++) {
47             // 对该行,所有的列遍历
48             if (col.contains(i) || pie.contains(i+row) || na.contains(i-row)) { continue; }
49 
50             // 符合条件:继续走
51             col.add(i);
52             pie.add(i+row);
53             na.add(i-row);
54             curRes.add(i);
55 
56             DFS(n, row+1, curRes, res);
57 
58             // 回到上一层,修正
59             curRes.remove(curRes.size()-1);
60             col.remove(i);
61             pie.remove(i+row);
62             na.remove(i-row);
63         }
64     }
65 }                

 

注意事项

在没有泛型类时,原始的 ArrayList 类提供的 get 方法别无选择只能返回 Object,因此,get 方法的调用者必须对返回值进行类型转换。

  啥意思呢?看下面的代码

 1         List<List<Integer>> test = new ArrayList<>();
 2         List<Integer> a = new ArrayList<>();
 3         a.add(1);
 4         a.add(2);
 5 
 6         List<Integer> b = new ArrayList<>();
 7         b.add(4);
 8         b.add(5);
 9         b.add(6);
10 
11         test.add(a);
12         test.add(b);
13 
14         for (List e: test) {
15             for(Object o: e) {
16                 // 这里为何是Object类型???虽然声明的时候是Integer类型,但是e没有声明泛型类
17                 // 在没有泛型类时,原始的ArrayList类提供的get方法返回的只能是Object类型,get方法调用者必须对返回值进行类型转换。
18                 System.out.println((int)o);
19             }
20             System.out.println("----------");
21         }

  如何解决呢,声明泛型类

1  for (List<Integer> e: test) {
2             for(int o: e) {
3                 System.out.println(o);
4             }
5             System.out.println("----------");
6  }

 

原文地址:https://www.cnblogs.com/dogeLife/p/11101057.html