数据结构-Java实现-简单递归

本文深入探讨了猴子吃桃问题的不同解决方法,包括迭代与递归;介绍了最大公约数与最小公倍数的高效算法;提供了多种1到100求和的方法,并分析了各自的时间与空间复杂度;同时详细讲解了斐波那契数列的经典实现,如递归、备忘录法、动态规划等。

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

猴子吃桃

//每天吃一半多一个,最后一天只剩1个
public class MonkeyEatFruit {
    pulic int eat01(int n){
        int a=1;
        for(int i=2;i<=n;i++){
            a=2*a+2;
        }
        return a;
    }
    public int eat02(int n){
        if(n==1){
            return 1;
        }else{
            int a=eat02(n-1)*2+2;
            return a;
        }
    }
    public int eat03(int n){
        return n==1?1:eat03(n-1)*2+2;
    }
    public void check(int n, int num){
        int a=num;
        for(int i=2;i<=n;i++){
            a=a/2-1;
        }
        System.out.println(num);
        //验证
        //断言:AssertTrue
        Assert.assertTrue(a==1);
    }
    @Test
    public void test01(){
        int n=10;
        int num=eat01(n);
        System.out.println(num);
    }
}

最大公约数与最小公倍数

//时间复杂度都为O(lgN),程序在执行过程中每执行一次循环,m或n至少有一个缩小了2倍,时间复杂度上限为log(2)M,大量平均下为lgM。
//gcd01空间复杂度为O(1)
//gcd02的空间复杂度为O(lgN)
public class GcdAndLcm {
    //最大公约数求解
    public int gcd01(int m, int n){
        int a=Math.max(m, n);
        int b=Math.min(m, n);
        m=a;
        n=b;
        int r;
        while(m%n !=0){
            r=m%n;
            m=n;
            n=r;
        }
        return n;
    }
    public int gcd02(int m, int n){
        int a=Math.max(m, n);
        int b=Math.min(m, n);
        if(a%b==0){
            return b;
        }else{
            return gcb02(b,a%b   )
        }
    }
    //简洁代码
    public int gcd03(int m, int n){
        return m>=n?m%n==0?n:gcd03(n,m%n):n%m==0?m:gcd03(m,n%m);
    }
    @Test
    public void testGcd03(){
        System.out.println(gcd01(100,4));
        System.out.println(gcd01(4,100));

    }   
    //最小公倍数求解
    //最小公倍数=乘积/最大公约数
    public int lcm(int m, int n){
        return m*n/gcd01(m, n);
    }

    @Test
    public void testLcm(){
        System.out.println(lcm(100,4));
    }
}

1到100累加

public class CommonSum{
    //非递归的普通算法T(n)=n,S(n)=O(1)
    public int commenMethod01(int n){
        int sum=0;
        for(int i=0;i<=;i++){
            sum+=i;
        }
        return sum;
    }
    //递归算法,T(N)=O(1),S(N)=O(N)
    public int commenMethod02(int n){
        if(n==1){
            return 1;
        }else{
            return commenMethod02(n-1)+n;
        }
    }
    //等差数列求和公式,T(N)=S(N)=O(1)
    public int commenMethod03(int n){
        return n*(n+1)/2;
    }
    @TestDTM
    public void test(){
        int n=100;
        System.out.println(commenMethod01(100)+" "+commenMethod02(100)+“ ”+commenMethod03(100);
    }
}
//抛出异常意外终止,采用数组越界异常,T(N)=O(1),S(N)=O(N)
//array[i]用于存取前i个数字的和,越界返回array[100]也就是1到100求和
public class SumExceptionMethod{
    private int n;
    private int[] array;
    public SumExceptionMethod(){
        super();
    }
    public SumExceptionMethod(int n){
        super();
        this.n=n;
        array=new int[n+1];
    }
    public int sumMethod(int i){
        try{
            array[i]=array[i-1]+i;  //公差i到时候设为1就ok
            int k=sumMethod(i+1);  //递归调用
            return k;
        } catch (ArrayIndexOutOfBoundsException e){
            return array[n];
        }
    }
}
//构造函数递归 T(N)=O(1),S(N)=O(N)
public class SumExceptionConstructor {
    public static int n;
    public static in[] array;
    public SumExceptionConstructor(int i){
        try{
            array[i]=array[i-1]+i;
            new SumExceptionConstructor(i+1);
        } catch (ArrayIndexOutOfBoundsException e){
            System.out.println(array[n]);
            return;
        }
    }
}
public class TestSum{
    @Test
    public void testSum(){
        int n=100;
        SumExceptionMethod sem=new SumExceptionMethod(n);
        int sum=sem.sumMethod(1);
        System.out.println(sum);
    }
    @Test
    public void testConstructor(0){
        int n=100;
        SumExceptionConstructor.n=n;
        SumExceptionConstructor.array=new int[n+1];
        new SumExceptionConstructor(1);
    }
}

斐波那契数列

//经典爬楼梯问题
public class Climb{
    //分解策略
    //T(N)=(2^n) S(N)=O(N)
    public int fib01(int n){
        if(n==1||n==2){
            return n;
        }else{
            int k=fib01(n-1)+fib01(n-2);
            return k;
        }
    }
    public int fib02(int n){
        return n==1||n==2?n:fib02(n-1)+fib02(n-2);
    }
    //备忘录法,如果array[i]!=0直接返回,array[i]=0,array[i]=f(i-1)+f(i-2),返回arrau[i]
    //T(N)=(N) S(N)=O(N)
    public int dfs(int n, int[] array){
        if(array[n]!=0){
            return array[n];
        }else{
            array[n]=dfs(n-1, array)+dfs(n-2, array);
            return array[n];
        }
    }

    public int fib03(int n){
        if(n==1||n==2){
            return n;
        }else{
            int[]=new int[n+1];
            array[1]=1;
            array[2]=2;
            return dfs(n, array);
        }
    }
    //动态规划法
    //T(N)=O(N) S(N)=O(N)
    public int fib04(int n){
        if(n==1||n==2){
            return n;
        }else{
            int[]=new int[n+1];
            array[1]=1;
            array[2]=2;
            for(int i=3; i<=n; i++){
                array[i]=array[i-1]+array[i-2];
            }
            return array[n];
        }
    }
    //状态压缩法
    public int fib05(int n){
        if(n==1||n==2){
            return n;
        }else{
            int a=1;
            int b=2;
            int t;
            for(int i=3;i<n;i++){
                t=a+b;
                a=b;
                b=t;
            }
            return b;
        }
    }
    //通项公式法
    //T(N)=O(log(2)N) S(N)=O(1)
    public int fib06(int n){
        if(n==1||n==2){
            return n;
        }else{
            double sqrtFive=Math.sqrt(5);
            n++;
            double a=Math.pow(1+sqrtFive/2,n);
            double b=Math.pow(1-sqrtFive/2,n);
            double result=1/sqrtFive*(a-b);
            return (int)Math.floor(result);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值