递归与迭代,台阶问题,斐波那契,分治算法

问题:有n步台阶,一次只能上1步或2步,共有多少种走法?

解法:

        (1)递归

        (2)循环迭代

递归

 

注:对于每一种我们只关心他最后一步的两种可能,一种是还差一步,一种是还差两步,这两种可能相加就可以关心他最后是 一步跨两个台阶 还是 一步跨一个台阶。

        解释:假设当n=3时,他跨完所有台阶有两种情况,一种是最后一次是踏一步踏完台阶,另一种是最后一次踏两步踏完台阶,图中n=3时的两种情况就是如此。

        图中演示的并不是

                第一种情况:踏一步-踏一步-踏一步-踏完

                第二种情况:踏一步-踏两步-踏完

                第三种情况:踏两步-踏一步-踏完

        n=1时有多少种走法,n=2时有多少种走法,这两种加起来就是n=3时有多少种走法。f(2)里包含了f(1),f(n)最后一次的走法往前推,最后一次的走法要么是n-1步,要么是n-2步。即要么走一步要么走2步,由此引入f(n-1)和f(n-2),f(n)=f(n-1)+f(n-2),由大往小调,大的不断调用小的,一步一步往前推。
       

代码如下:

package org.example.step;

import org.junit.Test;

public class TestStep{

    @Test
    public void test(){
        long start = System.currentTimeMillis();
        System.out.println(f(100));//165580141
        long end = System.currentTimeMillis();
        System.out.println(end-start);//586ms
    }

    //  实现f(n):求n步台阶,一共有几种走法
    //  f(n)=f(n-1)+(n-2)
    public int f(int n){
        if(n<1){
            throw new IllegalArgumentException(n + "不能小于1");
        }
        if(n==1 || n==2){
            return n;
        }
        return f(n-2) + f(n-1);
    }
}

循环迭代:

注:one和two作为变量把状态保存了,两种方法看似相同,很大不同。递归是倒推,大的不断往前得到小的。循环迭代是顺推,小的累积得到大的。

代码如下:

package org.example.step;

import org.junit.Test;

public class TestStep2 {

    @Test
    public void test(){

        long start = System.currentTimeMillis();
        System.out.println(loop(100));//165580141
        long end = System.currentTimeMillis();
        System.out.println(end-start);//<1ms
    }

    public int loop(int n){
        if(n<1){
            throw new IllegalArgumentException(n + "不能小于1");
        }
        if(n==1 || n==2){
            return n;
        }

        /*
        * 对于下面两行结合图来看,图中显示  two = f(1); one = f(2)
        * f(1)指跨1步,f(2)指跨2步
        * */
        int one = 2;// 初始化为到达共3级台阶跨2步台阶还差1步台阶的走法(初始化为走到第二级台阶的走法--原文)
        int two = 1;// 初始化为到达共3级台阶跨1步台阶还差2步台阶的走法(初始化为走到第一级台阶的走法--原文)

        // 定义一个参数,赋值0仅是初始化一下
        int sum = 0;

        for(int  i=3; i<=n; i++){
            // 最后跨2步 + 最后跨1步的走法
            sum = two + one;

            // two = n-1 时的one,one = n-1 时的sum
            two = one;
            one = sum;
        }
        return sum;
    }
}

对于上面两种方法的总结:

(1)递归相较于循环迭代效率低,但简洁易懂;循环迭代相较于递归效率高,但稍微复杂一些,且不易理解。

(2)两种方法看似相同,很大不同。递归是倒推,大的不断往前得到小的。循环迭代是顺推,小的累积得到大的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值