Algorithm-1-Recursion

One, recursion

1. Concept

A certain method calls the method itself, which is called recursion ( recursion)

Need to pay attention to the number of recursion, if too many times, it may cause stack overflow ( java.lang.StackOverflowError)

Use recursion, modify the method to enter the parameters, and keep trying to achieve the desired result. This process is called backtracking

The advantage of this method is simple, but the disadvantage is that there may be too many backtracking executions.

2. Application

[1] Maze problem

In a plane (two-dimensional array), there are walls all around, so you cannot pass through. There is a target value, in a certain position. Now you need to start searching from the specified location, and ask how to find the target location

analysis:

You cannot pass through the wall, and you cannot go where you have already passed. To find the target location, there are 4 directions to go at any point. So you can use backtracking thinking, constantly retry 上、下、左、右four directions until it reaches the target position

Example:

class Maze {
    
    
    private final int width;
    private final int length;
    private final int[][] map;

    /** 初始化坐标位置 */
    private final int INIT_X = 2;
    private final int INIT_Y = 2;

    /** 墙体 */
    private final int WALL = 1;

    /** 还未通过的地方 */
    private final int PATH = 0;

    /** 已经通过的地方 */
    private final int PASS = 2;

    /** 目标 */
    private final int TARGET = 9;

    /** 查找次数 */
    private int count = 0;

    public Maze(int width, int length) {
    
    
        if (width < 5 || length < 5) {
    
     // 宽高至少为5
            throw new IllegalArgumentException("非法宽高!");
        }

        this.width = width;
        this.length = length;
        this.map = new int[length][width];

        this.init();
    }

    private void init() {
    
    
        // 初始化墙体
        for (int i = 1, len = width - 1; i < len; i++) {
    
    
            map[0][i] = WALL;
            map[length - 1][i] = WALL;
        }
        for (int j = 0; j < length; j++) {
    
    
            map[j][0] = WALL;
            map[j][width - 1] = WALL;
        }

        for (int k = 1; k <= INIT_Y; k++) {
    
    
            map[INIT_X + 1][k] = WALL;
        }

        // 初始化目标
        map[length - 2][width - 2] = TARGET;
    }

    public void find() {
    
    
        find(INIT_X, INIT_Y);
    }

    private boolean find(int x, int y) {
    
    
        this.count++;

        if (TARGET == map[x][y]) {
    
    
            this.show();
            System.out.println("\n共查找了" + count + "次");
            return true;
        }

        if (PATH == map[x][y]) {
    
    
            map[x][y] = PASS;

            if (upFind(x, y)) {
    
    
                return true;
            } else if (rightFind(x, y)) {
    
    
                return true;
            } else if (downFind(x, y)) {
    
    
                return true;
            } else if (leftFind(x, y)) {
    
    
                return true;
            }
        }

        return false;
    }

    private boolean upFind(int x, int y) {
    
    
        return find(x - 1, y);
    }

    private boolean rightFind(int x, int y) {
    
    
        return find(x, y + 1);
    }

    private boolean downFind(int x, int y) {
    
    
        return find(x + 1, y);
    }

    private boolean leftFind(int x, int y) {
    
    
        return find(x, y - 1);
    }

    private void show() {
    
    
        for (int i = 0; i < length; i++) {
    
    
            for (int j = 0; j < width; j++) {
    
    
                System.out.print(map[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println();
    }

}

[2] The Eight Queens Problem

On a chess board (8 * 8), 8 queens must be placed so that each queen cannot attack each other (2 queens cannot exist in the horizontal, vertical and diagonal directions). Ask how many kinds of pendulums are there

Analysis: You can use the retrospective method. Use an array with a length of 8 to represent the horizontal (or vertical) positions of the 8 queens. First, by looping the array (the subscript is the horizontal or vertical position of the queen placement position), get the current queen placement position. Then through constant recursion, get the placement position of the next queen, and finally get all the placement methods

Example:

class EightQueens {
    
    
    private static final int EIGHT = 8;
    private static int count = 0;
    private static int sum = 0;

    public static void pattern() {
    
    
        pattern(EIGHT);
    }

    public static void pattern(int length) {
    
    
        int[] array = new int[length];
        pattern(array, length, 0);

        System.out.println("一共有" + sum + "种摆法");
        System.out.println("一共校验了" + count + "次");
    }

    private static void pattern(int[] array, int length, int index) {
    
    
        if (length == index) {
    
    
            for (int i = 0; i < length; i++) {
    
    
                System.out.print(array[i] + " ");
            }
            System.out.println();
            sum++;
            return;
        }

        for (int i = 0; i < length; i++) {
    
    
            array[index] = i;
            if (check(array, index)) {
    
     // 循环判断当前索引位置是否可以摆放皇后
                pattern(array, length, index + 1); // 继续摆放下一个皇后
            }
        }
    }

    private static boolean check(int[] array, int index) {
    
    
        count++;
        for (int i = 0; i < index; i++) {
    
    
            // 校验水平或垂直位置是否有皇后存在,以及校验斜线方向是否存在皇后
            if (array[i] == array[index] || (index - i) == Math.abs(array[index] - array[i])) {
    
    
                return false;
            }
        }
        return true;
    }

}

Guess you like

Origin blog.csdn.net/adsl624153/article/details/103866013