递归的详细讲解

概述

简介

程序调用自身的编程技巧称为递归,递归解决问题通常名为暴力搜索

三要素

明确递归终止条件

给出递归终止时的处理办法

可以提取重复逻辑,缩小问题规模

优点

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量

缺点

递归解决问题运行效率较低,因此应该尽量避免使用递归

在递归调用的过程中系统为每一层的返回点 ,局部量等开辟了栈来储存,递归次数过多可能会造成栈溢出。

解决递归问题的思路 

没思路时

1.画树

2.找出口

递归的两套模板


/**
 * 打印1-100
 */
public class Main {
    public static void main(String[] args) {
        f1(1);
        System.out.println();
        f2(100);
    }

    /**
     * 递的时候打印
     *
     * @param n
     */
    public static void f1(int n) {
        if (n <= 100) {
            System.out.print(n + " ");
            f1(n + 1);
        }
    }

    /**
     * 归的时候打印
     *
     * @param n
     */
    public static void f2(int n) {
        if (n >= 1) {
            f2(n - 1);
            System.out.print(n + " ");
        }
    }
}

简单算法

求斐波那契数列的第n项

问题

求斐波那契数列的第n项

波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55【每个数字是前两个数字的和】

实现

/**
 * 求斐波那契数列的第n项
 *
 * 波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55【每个数字是前两个数字的和】
 */
public class Main {
    public static void main(String[] args) {
        System.out.println(fibonacci(5));
    }

    public static int fibonacci(int n) {
        if (n > 1) {
            return fibonacci(n - 1) + fibonacci(n - 2);
        } else {
            return n;
        }
    }
}
          

爬楼梯问题 

问题

一个楼梯总共有n级台阶,你每次可以走1个台阶或者两个台阶,问从第0级台阶走到第n级台阶一共有多少种方案

思路

1.此算法类型为深度优先搜索 

2.可以画树

实现

/**
 * 爬楼梯问题
 *
 * 问题: 一个楼梯总共有n级台阶,问从第0级台阶走到第n级台阶一共有多少种方案。
 * 你每次可以走1个台阶或者两个台阶。
 */
public class Main {
    private static int res = 0;

    public static void main(String[] args) {
        f1(0, 4);
        System.out.println(res);
    }

    /**
     *
     * @param startFloor 开始台阶
     * @param endFloor 结束台阶
     */
    private static void f1(int startFloor, int endFloor) {
        //如果爬上了最后一层台阶,说明找到了一种方案
        if (startFloor == endFloor) {
            res++;
        }
        //如果没有爬完,则可能爬1或者2阶台阶
        if (startFloor < endFloor) {
            f1(startFloor + 1, endFloor);
            f1(startFloor + 2, endFloor);
        }
    }
}
          

中等算法

全排列

来源

. - 力扣(LeetCode)

题目

给定一个不含重复数字的整数数组 nums ,返回其所有可能的全排列 ,可以按任意顺序返回答案

思路

实现

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

class Solution {
    //全排列集合
    List> itemList = new ArrayList();
    //存放每一个方案的数组
    List item = new ArrayList();
    //用于判断当前数字有没有被用过的数组
    boolean[] haveUse;

    public List> permute(int[] nums) {
        haveUse = new boolean[nums.length];
        f(0, nums);
        return itemList;
    }

    void f(int start, int[] nums) {
        //如果所有数都被用过了,说明找到了一组方案
        if (start == nums.length) {
            itemList.add(new ArrayList(item));
        }
        //否则就循环遍历数组
        for (int i = 0; i < nums.length; i++) {
            if (!haveUse[i]) {
                item.add(nums[i]);
                haveUse[i] = true;//加入方案数组后,标记该数字被使用
                f(start + 1, nums);
                // 回溯
                haveUse[i] = false;
                item.remove(item.size() - 1);
            }
        }
    }
}

           

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月木@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值