zoukankan      html  css  js  c++  java
  • 《Java算法》Java回溯算法

    1. 概要

    回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。 

    2. 原理

    我们通过皇后问题来讲解回溯算法。

    回溯算法经典案例皇后问题:

    n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
    给定一个整数 n,返回所有不同的n皇后问题的解决方案。
    每一种解法包含一个明确的n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。

    示例:   输入: 4 

    // 解法 1                                                                             // 解法 2
                   

    解释: 4 皇后问题存在两个不同的解法。

    回溯算法原理图解:

    如何判断皇后是否会被攻击: 横排,竖排好判断,对角线如何判断

    根据图解找到对角线规律。

    3 代码:

    import java.util.ArrayList;
    import java.util.List;
    
    public class Subject98 {
    
        //竖排被占登记,用于判断是否能够被竖排攻击
        int rows[]; //
        // "从左到右对角线" 登记,用于判断是否能够被竖排攻击
        int hills[];
        // "从右到左对角线" 登记,用于判断是否能够被竖排攻击
        int dales[];
        int n;
        // output
        List<List<String>> output = new ArrayList();
        // 皇后的位置
        int queens[];
    
        public static void main(String[] args) {
            List<List<String>> listList = new Subject98().solveNQueens(6);
            System.out.println(listList);
        }
    
        /**
         * 判断该位置是否会被攻击
         * @param row
         * @param col
         * @return
         */
        public boolean isNotUnderAttack(int row, int col) {
            int res = rows[col] + hills[row - col +  n - 1] + dales[row + col];
            return (res == 0) ? true : false;
        }
    
        /**
         * 将皇后放入该位置
         * @param row
         * @param col
         */
        public void placeQueen(int row, int col) {
            queens[row] = col;   //将皇后位置放入
            rows[col] = 1;   //竖排攻击位置
            hills[row - col +  n - 1] = 1;  // "从左到右对角线" 攻击位置
            dales[row + col] = 1;   //"从右到左对角线" 攻击位置
        }
    
        /**
         * 回溯皇后位置
         * @param row
         * @param col
         */
        public void removeQueen(int row, int col) {
            queens[row] = 0;
            rows[col] = 0;
            hills[row - col + n - 1] = 0;
            dales[row + col] = 0;
        }
    
        /**
         * 将满足条件的皇后位置放入output中
         */
        public void addSolution() {
            List<String> solution = new ArrayList<String>();
            for (int i = 0; i < n; ++i) {
                int col = queens[i];
                StringBuilder sb = new StringBuilder();
                for(int j = 0; j < col; ++j) sb.append(".");
                sb.append("Q");
                for(int j = 0; j < n - col - 1; ++j) sb.append(".");
                solution.add(sb.toString());
            }
            output.add(solution);
        }
    
        public void backtrack(int row) {
            for (int col = 0; col < n; col++) {
                if (isNotUnderAttack(row, col)) {
                    placeQueen(row, col);
                    // 皇后数量是否满足,满足则输出
                    if (row + 1 == n) addSolution();
                    // 不满足则继续
                    else backtrack(row + 1);
                    // 回溯。
                    removeQueen(row, col);
                }
            }
        }
    
        public List<List<String>> solveNQueens(int n) {
            this.n = n;
            rows = new int[n];
            hills = new int[2 * n - 1];
            dales = new int[2 * n - 1];
            queens = new int[n];
    
            backtrack(0);
            return output;
        }
    }

    来源:https://leetcode-cn.com/problemset/all/

    This moment will nap, you will have a dream; But this moment study,you will interpret a dream.
  • 相关阅读:
    jchdl
    jchdl
    UVa 10256 (判断两个凸包相离) The Great Divide
    UVa 11168 (凸包+点到直线距离) Airport
    LA 2572 (求可见圆盘的数量) Kanazawa
    UVa 10652 (简单凸包) Board Wrapping
    UVa 12304 (6个二维几何问题合集) 2D Geometry 110 in 1!
    UVa 10674 (求两圆公切线) Tangents
    UVa 11796 Dog Distance
    LA 3263 (平面图的欧拉定理) That Nice Euler Circuit
  • 原文地址:https://www.cnblogs.com/jssj/p/12098636.html
Copyright © 2011-2022 走看看