【搞定左神算法初级班】第7节:暴力递归、动态规划

这篇博客详细介绍了递归和动态规划的概念及应用,通过五个递归问题(如汉诺塔、字符串子序列、排列、母牛数量)和两个动态规划问题(矩阵最小路径和、背包问题)进行讲解,阐述了如何从暴力递归转换为动态规划,强调了动态规划避免重复计算和无后效性的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目 录:

一、递归

题目1:求 n! 的结果

题目2:汉诺塔问题

题目3:打印一个字符串的全部子序列,包括空字符串

题目4:打印一个字符串的全部排列

题目5:母牛每年生一只母牛,新出生的母牛成长三年后也能每年生一只母牛,假设不会死。求N年后,母牛的数量

二、动态规划

动态规划的特点

如何把暴力递归套路变为动态规划

题目1:矩阵最小路径和

题目2:(背包问题)从数组任意选择数字,能不能累加得到 aim


一、递归

  • 暴力递归的步骤:

  • 1:把问题转化为规模缩小了的同类问题的子问题;
  • 2:有明确的不需要继续进行递归的条件(base case);
  • 3:有得到了子问题的结果之后的决策过程;
  • 4:不记录每一个子问题的解。

递归其实就是不断的尝试,不知道明确的计算方式,但是明白怎么去试。

题目1:求 n! 的结果

用递归去求解时:很明显求解 n! 其实就是求解 (n - 1)! 的问题,即它的子问题.....

package com.offer.foundation.class6;

/**
 * @author pengcheng
 * @date 2019/3/30 - 21:27
 * @content: n! 问题
 */
public class Factorial {

    // 非递归版本
    public long getFactorial1(int n){
        long res = 1L;
        for (int i = 1; i <= n; i++) {
            res *= i;
        }
        return res;
    }

    // 递归版本
    public long getFactorial2(int n){
        if(n == 1){
            return 1L;
        }
        return (long) n * getFactorial2(n - 1);
    }

    // 测试
    public static void main(String[] args) {
        Factorial factorial = new Factorial();
        System.out.println(factorial.getFactorial1(5));   // 120
        System.out.println(factorial.getFactorial2(5));   // 120
    }
}

题目2:汉诺塔问题

  • 打印 n 层汉诺塔从最左边移动到最右边的全部过程:

题目:在一根柱子上从下往上按照大小顺序摞着 n 片黄金圆盘。把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。打印出移动次数最少的全过程。

  • 【分析】:给三根柱子分别命名为 “left”、“mid”、“right”,from 代表此次需要移动的圆盘所在的位置,to 代表这些圆盘要去的地方,help 是用于辅助的,分三步走:
    • 1、n-1 个圆盘从 from 到 help;
    • 2、第 n 个圆盘从 from 到 to;
    • 3、把那 n-1个圆盘从 help 移动到 to 上面来。
  • 时间复杂度:f(n) = 2f(n-1) +1,是2(n-1)

把尝试的能力写成代码就是递归的过程。

package com.offer.foundation.class6;

/**
 * @author pengcheng
 * @date 2019/3/30 - 22:18
 * @content: 汉诺塔问题
 */
public class Hanoi {

    public void hanoi(int n){
        if(n > 0){
            hanoi(n, "left", "right", "mid");
        }
    }

    /**
     * @param n :n个数
     * @param from :原位置
     * @param help :辅助位置
     * @param to : 目标位置
     */
    public void hanoi(int n, String from, String to, String help){
        if(n == 1){
            // 只有一个时,直接移到目标位置即可
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值