5.迭代与递归

本文探讨了一个经典的编程问题——爬楼梯问题,分别通过递归和迭代两种方式求解,并对比了这两种方法的优缺点。递归方法虽然代码简洁易懂,但存在调用栈过深的问题;而迭代方法虽然牺牲了一定的代码简洁性,但拥有更好的运行效率。

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

首先看一道编程题如下:
有 n 步台阶,一次只能上 1 步或者 2 步,共有多少种走法?


/**
 * 递归
 * 编程题:有 n 步台阶,一次只能上 1 步或者 2 步,共有多少种走法
 *
 * 递归
 * 分析如图,当 n 等于 1 或者 2 时,走法就等于 n,从第三层台阶开始,每一层台阶为前两层台阶走法之和。
 * .n=1     ->一步                                            ->f(1)=1
 * ·n=2     ->(1)一步一步(2)直接2步                         ->f(2)=2
 * ·n=3     ->(1)先到达f(1),然后从f(1)直接跨2步           ->f(3)=f(1)+f(2)
 *            (2)先到达f(2),然后从f(2)跨1步
 * ·n=4     ->(1)先到达f(2),然后从f(2)直接跨2步           ->f(4)=f(2)+f(3)
 *            (2)先到达f(3),然后从f(3)跨1步
 *
 * ·n=x     -> (1)先到达子(x-2),然后从f(-力真接跨2步        ->f(x)=f(x-2)+f(x-1)
 *            (2)先到达f(x-1),然后从f(x-1)跨1步
 */
public class Recursion {

    @Test
    public void test() {
        // 时间复杂度 ...
        long start = System.currentTimeMillis();
        System.out.println(recursion(40)); // 165580141
        long end = System.currentTimeMillis(); // 537
        System.out.println(end - start);
    }

    // 递归实现
    public int recursion(int n) {
        if(n < 1) {
            return 0;
        }
        if(n == 1 || n == 2) {
            return n;
        }
        return recursion(n - 2) + recursion( n - 1);
    }
}
/**
 * 迭代
 * 用 one、two 这两个变量来存储 n 的最后走一步和最后走两步,从第三层开始走,用 sum 来保存前两次的走法的次数,sum = two + one; 然后 two 移到 one,one 移到 sum 循环迭代。
 *
 * ·n=1->(1)一步                           	->f(1)=1
 * ·n=2->(1)一步一步(2)直接2步                 ->f(2)=2
 * ·n=3->(1)先到达f(1),然后从f(1)直接跨2步   ->f(3)= two + one
 *       (2)先到达f(2),然后从f(2)跨1步         f(3)=f(1)+f(2)
 *                                                two=f(1);one=f(2)
 * ·n=4->(1)先到达f(2),然后从于(2)直接跨2步  ->f(4)= two + one
 *       (2)先到达f(3),然后从f(3)跨1步        f(4)=f(2)+f(3)
 *                                               two=f(2);one=f(3)
 * ·n=x->(1)先到达f(x-2),然后从f(x-2)直接跨2步->f(x)= two + one
 *        (2)先到达f(x-1),然后从f(x-1)跨1步      f(x)=f(x-2)+f(x-1)
 *                                                 two=f(x-2);one=f(x-1)
 */
public class Iteration {

    @Test
    public void test() {
        // 时间复杂度 O(n)
        long start = System.currentTimeMillis();
        System.out.println(iteration(40)); // 165580141
        long end = System.currentTimeMillis(); // 0
        System.out.println(end - start);
    }

    // 迭代实现
    public int iteration(int n) {
        if(n < 1) {
            return 0;
        }
        if(n == 1 || n == 2) {
            return n;
        }
        int two = 1; // 一层台阶,有 1 走法, n 的前两层台阶的走法
        int one = 2; // 二层台阶,有 2 走法, n 的前一层台阶的走法
        int sum = 0; // 记录一共有多少中走法
        for(int i = 3; i <= n; i++) {
            sum = two + one;
            two = one;
            one = sum;
        }
        return sum;
    }
}

总结:
1)方法调用自身称为递归,利用变量的原值推出新值称为迭代。
2)递归
优点:大问题转化为小问题,可以减少代码量,同时代码精简,可读性好;
缺点:递归调用浪费了空间,而且递归太深容易造成堆栈的溢出。
3)迭代
优点:代码运行效率好,因为时间复杂度为 O(n),而且没有额为空间的开销;
缺点:代码不如递归简洁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zkhyzy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值