数据结构与算法(五)之递归

递归简介

递归算法的基本思想是:把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。

一个问题要采用递归方法来解决时,必须符合以下三个条件:

  1. 解决问题时,可以把一个问题转化为一个新的问题,而这个新的问题的解决方法仍与原问题的解法相同,只是所处理的对象有所不同,这些被处理的对象之间是有规律的递增或递减;

  2. 可以通过转化过程是问题得到解决;

  3. 必定要有一个明确的结束递归的条件,否则递归将会无止境地进行下去,直到耗尽系统资源。也就是说必须要某个终止递归的条件。如求阶乘问题,我们要求n的阶乘(n!),可以把这个问题转化为n*(n-1)!,而要求(n-1)!又可转化为(n-1)*(n-2)!,……,这里面都有一个一个数乘以另一个数阶乘的问题,被处理的对象分别是n,n-1,……,是有规律的递减。但是我们不能让程序无休止的乘下去,必须要给他一个结束条件,该问题恰好有一个结束条件,那就是当n=0时,0!=1。

迷宫回溯问题

原题:
https://www.nowcoder.com/questionTerminal/cf24906056f4488c9ddb132f317e03bc

代码实现

//i表示当前坐标的横坐标,j表示纵坐标,input代表迷宫,res路径信息
    public static boolean mazeTrack(int[][] input, int i, int j, int rowNum, int colNum, Stack<String> res) {
        //如果到达终点返回true
        if (input[rowNum - 1][colNum - 1] == 2) return true;
        //如果是墙或者路已经走了,返回false
        if (i < 0 || i >= rowNum || j < 0 || j >= colNum || input[i][j] != 0) {
            return false;
        }
        //说明路暂时可以走,标为2
        input[i][j] = 2;
        //递归判断上下左右是否有路,如果都为false,这个地方封路
        if (!mazeTrack(input, i, j + 1, rowNum, colNum, res) && !mazeTrack(input, i + 1, j, rowNum, colNum, res) && !mazeTrack(input, i - 1, j, rowNum, colNum, res) && !mazeTrack(input, i, j - 1, rowNum, colNum, res)) {
            input[i][j] = 1;
            return false;
        }
        res.push("(" + i + "," + j + ")");
        return true;
    }

八皇后问题

原题:
https://www.nowcoder.com/practice/de1e1ff46cd641178a147166156c9d83?tpId=3&tqId=10896&rp=0&ru=/ta/hackathon&qru=/ta/hackathon/question-ranking

代码实现

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    //存放棋盘和皇后的数量
    private static final int QUEEN_NUM = 8;
    //存储最终结果
    List<String> finalRes;
    //存储皇后位置
    List<Integer> nowRes;

    public Main() {
        finalRes = new ArrayList<>();
        nowRes = new ArrayList<>();
    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        Main m = new Main();
        m.queueProblem(0);

        while (cin.hasNext()) {
            int i = cin.nextInt();
            System.out.println(m.finalRes.get(i - 1));

        }
    }

    public void queueProblem(int i) {

        // 遍历当前行的所有单元格 以行为单元
        for (int j = 0; j < QUEEN_NUM; j++) {
            // 是否能够放置皇后
            if (check(i, j)) {
                nowRes.add(j);
                if (i == QUEEN_NUM - 1) {
                    // 最后行放置完毕 放入空间
                    finalRes.add(listToString());
                } else {
                    // 放置下一行
                    queueProblem(i + 1);
                }

                //回退到当前步骤,把皇后设置为0
                nowRes.remove(i);
            }

        }
    }


    public boolean check(int i, int j) {
        for (int x = 0; x < nowRes.size(); x++) {
            int y = nowRes.get(x);
            //检查列 检查右下 检查左下
            if (y == j || Math.abs(i - x) == Math.abs(y - j)) {
                return false;
            }
        }
        return true;

    }

    public String listToString() {
        String res = "";
        for (int i : nowRes) {
            res += i + 1;
        }
        return res;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值