怎么能忘了N皇后(N Queens)?

n皇后问题很简单,它是一个循环+递归实现回溯算法的一个很好示例。

外层循环保证列方向遍历,内层递归保证行方向遍历。综合起来便可遍历整个搜索空间。

解决问题的关键是知道要保存什么。

递归中要保存的是前面几层的位置信息,以及当前递归层数。

位置信息用于判断是否冲突。递归层数用于判断递归是否结束。

怎么判断是否冲突?这就需要对矩阵的信息存储有所了解。

矩阵同行,同列都好判断,那么同一主对角线,同一副对角线怎么判断?

同一主对角线上行号与列号之和都相等。同一副对角线上行号与列号之差都相等。

知道了这些,N皇后就不难写出了。

下面给出java实现代码。

 1 package com.company;
 2 
 3 /**
 4  * n皇后问题实际上很简单。
 5  * Created by zqiguo on 2017/2/28.
 6  */
 7 public class NQueens {
 8 
 9     /**
10      * count用于计数解法个数。
11      */
12     private static int count = 0;
13 
14     /**
15      * n皇后递归函数
16      * @param n  皇后个数
17      * @param row  当前行号
18      * @param pos  前row-1 行放置的皇后位置信息。比如(0,pos[0]),表示第0行皇后放置在第pos[0]列。
19      */
20     private static void nQueens(int n, int row, int[] pos){
21         if (row == n){
22             count++;
23             return;
24         }
25         for (int i = 0; i < n; i++) {
26             int conflictFlag = 0;
27             for (int j = 0; j < row; j++) {
28                 if (i == pos[j] || pos[j] - j == i - row || pos[j] + j == i + row){
29                     conflictFlag = 1;
30                 }
31             }
32             if (conflictFlag == 0){
33                 pos[row] = i;
34                 nQueens(n,row+1,pos);
35             }
36         }
37     }
38 
39     /**
40      * n皇后外部调用接口, 返回解法个数
41      * @param n  皇后个数
42      * @return 解法个数
43      */
44     public static int nQueens(int n){
45         int[] pos = new int[n];
46         nQueens(n,0,pos);
47         return count;
48     }
49 
50     public static void main(String[] args){
51         System.out.println(nQueens(8));
52     }
53 }

最近知乎上有一股邪风,说什么1行实现某某算法。以我个人来看,代码效率与可读性最重要。有时可读性还要在效率之上。

那些标榜1行实现某某某的,代码可还能看?更何况不换行,不加{},就是1行实现了?

原文地址:https://www.cnblogs.com/zqiguoshang/p/6531390.html