递归和回溯经典题目--n皇后问题

来源:互联网 发布:mongodb是什么数据库 编辑:程序博客网 时间:2024/05/18 13:28

      递归和回溯密不可分,可以把递归的过程就是回溯的过程。其中BFS,DFS等经典问题都是与递归和回溯的思想紧密相关的。我们可以不用纠结于每个问题的标签,只要能运用相关的思想解决问题即可。下边,来讨论一下回溯和递归的经典算法问题:n皇后问题。

问题描述:



我们可以把此问题看成递归图:



  此题关键是:如何判断冲突。也就是列,对角冲突







Java实现的代码如下:


package com.algorithm;import java.util.ArrayList;import java.util.List;/** * @Description: n皇后问题 * @author: Jingzeng Wang * @Date: Created in 18:41  2017/12/13. */public class NQueen {    // 保存全部结果    static List<List<String>> reslut = new ArrayList<>();    // 下边的集合完全可以用数组来替代,如果知道n的话。将n放在外部即可。    // 保存列是否冲突. 若i列放置了就置其为true    static List<Boolean> col = new ArrayList<>();    // 保存对角是否冲突 规律  行+列  0 -- (n-1) 用来判断对角线是否有冲突    static List<Boolean> dia1 = new ArrayList<>();    // 保存对角是否冲突 规律  列-行  -(n-1) -- (n-1) 用来判断对角线是否有冲突    static List<Boolean> dia2 = new ArrayList<>();    public static void main(String[] args) {        // n皇后        int n = 11;        // 初始化集合        for (int i = 0; i < n; i++) {            col.add(false);        }        // 对角线数 2*n-1        for (int i = 0; i < 2 * n - 1; i++) {            dia1.add(false);            dia2.add(false);        }        // 保存每次的结果        List<Integer> res = new ArrayList<>();        generateQueen(n, 0, res);        printResult(n);    }    /**     * 递归回溯求解n皇后     *     * @param n     n皇后     * @param index 第index行     * @param res   保存一次搜索结果     */    private static void generateQueen(int n, int index, List res) {        if (index == n) {            reslut.add(formatResult(n, res));            return;        }        // 遍历每一列可放置的位置        for (int i = 0; i < n; i++) {            // 判断列,对角线,是否可进行放置            if (!col.get(i) && !dia1.get(i + index) && !dia2.get(index - i + n - 1)) {                res.add(i);                col.set(i, true);                dia1.set(i + index, true);                dia2.set(index - i + n - 1, true);                // 递归寻找下一行                generateQueen(n, index + 1, res);                // 遍历完i列的可能结果后,回溯状态,继续下一列                col.set(i, false);                dia1.set(i + index, false);                dia2.set(index - i + n - 1, false);                res.remove(res.size() - 1);            }        }        return;    }    /**     * 格式化结果     *     * @param n     * @param res     * @return     */    private static List<String> formatResult(int n, List res) {        List<String> list = new ArrayList<>();        for (int i = 0; i < n; i++) {            StringBuffer sb = new StringBuffer();            for (int j = 0; j < n; j++) {                if ((int) res.get(i) == j) {                    sb.append("Q ");                    continue;                }                sb.append(". ");            }            list.add(sb.toString());        }        return list;    }    /**     * 打印结果     *     * @param n     */    private static void printResult(int n) {        int count = 1;        for (List<String> singleRes : reslut) {            System.out.println(count++);            for (String s : singleRes) {                System.out.println(s);            }            System.out.println();        }        System.out.println(n + "皇后问题,共" + (count - 1) + "种结果!");    }}





原创粉丝点击