题目: Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.
就是让你输出N皇后问题的解法数目。
直接求解,每次还记录整个棋盘位置那种方法就不说了,必须超时。
有一个牛逼大了的超级无敌帅的位移动解法。我们暂且不表。看看我当时想的一个解法。
首先,对于皇后的那个递归方法,我有三个变量分别表示1.一个int值,表示递归到当前的level,当前的哪几个col被占领了,例如11011就表示我们下一个Q只能放在第三个(从第一个位置开始数)位置上了;2.一个hash table, 表示左对角线到目前为止,是否有Queen占领过了;2.一个hash table,表示右对角线是否有Queen占领过了。然后每次都去查询row上的可用格子,再去看看两个hash table上的可用格子,一起决定这一层我们选取那一(几)个作为备选项。
说说那个表示对角线的hash table,是一个Integer到boolean的映射。因为,所有某条固定左对角线上的点(row, col),row - col都是定值,那么可以用row - col表示一条左对角线嘛!同理可以用row + col表示右对角线嘛。
然后任意一个点,我们就知道它左右对角线的key了,就可以去那个hash 表里面查看是不是有Queen占领过啦。
所以,给出一个当前被占领的状态,一个左对角线被占领的状态,一个右对角线被占领的状态,我们就可以计算出下一步在哪里放Queen啦。方法如下:
1 private static int available(int cur_row_status, 2 HashMap<Integer, Boolean> left_digra_status, HashMap<Integer, Boolean> right_digra_status, int row, int n){ 3 int avail = cur_row_status; 4 for(int j = 0; j < n; j++){ 5 if((left_digra_status.containsKey(row + j) && left_digra_status.get(row + j)) 6 || (right_digra_status.containsKey(row - j) && right_digra_status.get(row - j))) avail = set(avail, j); 7 } 8 return avail; 9 }