Java学习历程之————进阶篇(十)

千禧难题之一:

       1、P = NP? 即P(polynomia)问题对NP(nondeterministic polynomial)问题,被看作逻辑和计算机科学中最突出的问题之一。它是斯蒂文·考克(Stephen Cook)于1971年陈述的,即P是否等于NP问题,至今为止,都没有人能给出完备的答案。

       P问题:能够在多项式时间内可用算法求解的问题。如n个数的排序问题,时间复杂度不超过O(n^2)。(即算法的时间复杂度为O(1),O(log(n)),O(n^a)此类问题)

       NP问题:不能在多项式时间内求解,但对于给出的任何答案,都可以快速验证该答案正确与否。如旅行商问题。(算法时间复杂度为O(a^n),O(n!)此类问题)                         

科普

知识

前言

     本周我们来学习递归算法,正所谓普通程序猿用迭代,大牛程序猿用递归,有了递归,不仅能减少我们的工作量,还能减轻计算机的运算量。那什么是递归呢?我们一起来看看吧~ 

一、递归

一、递归

      程序调用自身的编程技巧称为递归(recursion),在 Java 编程中,递归是允许方法调用自身调用的属性。调用自身的方法称为是递归的。那下面我们通过一个具体的例子来讲解一下在Java中,方法是如何调用自身的。

1.1 Fibonacci sequence

     相信大家对斐波那契数列都不陌生吧,说的就是有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

1.2 数学建模

     根据题意,我们若要求一年之内每个月兔子的数量,那就要先求出第十一个月和第十二个月兔子的数量,以此类推,需要依次求出前十一个月兔子的数量,我们可以得到以下数学模型:

1.3 编程实现

      对于递归的实现,我们首先需要定义一个方法,然后递归地调用该方法即可。

package jinjie10;
import java.util.Scanner;
public class fab {
    public static void main(String[] args){
        Scanner scan=new Scanner(System.in);
        System.out.print("需要输出第几个月后兔子的数量:");
        int n = scan.nextInt();
        long sum=0;
        for(int i=1;i<=n;i++){
            System.out.printf("第%d个月后兔子的数量为:%s\n",i,fab(i)+"\t");
            sum=sum+fab(i);
        }
    }
public static long fab(int n){//编写实现递归的方法
    if (n==1||n==2){
        return 1;
        }
    else {
        return fab(n-1)+fab(n-2);
        }
    }
}

二、递归的特性

二、递归的特性

      当一个方法调用它自身的时候,堆栈就会给新的局部变量和自变量分配内存,方法代码就带着这些新的变量从头执行。递归调用并不产生方法新的拷贝。只有参数是新的。每当递归调用返回时,旧的局部变量和自变量就从堆栈中清除,运行从方法中的调用点重新开始。递归方法可以说是像“望远镜”一样,可以自由伸缩。

      递归的主要优点在于:某些类型的算法采用递归比采用迭代算法要更加清晰和简单。例如快速排序算法按照迭代方法是很难实现的。还有其他一些问题,特别是人工智能问题,就依赖于递归提供解决方案。

注意事项:当编写递归方法时,你必须使用 if 条件语句在递归调用不执行时来强制方法返回。如果你不这么做,一旦你调用方法,它将永远不会返回。这类错误在使用递归时是很常见的。

三、实战

三、实战

下面我们来对比循环方法与递归方法

题目:求n!,即求n的阶乘问题

//求一个数字的阶乘
package jinjie10;
import java.util.Scanner;
public class jiecheng {
        public static void main(String[] args){
            Scanner n=new Scanner(System.in);
                System.out.print("请输入一个数字:");
                int num=n.nextInt();
                System.out.println("循环方法"+num+" 的阶乘为:" +fun(num));
                System.out.println("递归方法"+num+" 的阶乘为: " +recurrence(num));
            }
        //采用循环连乘法
        public static int fun(int num){
            int temp=1;
            int factorial=1;
            while(num>=temp){
                factorial=factorial*temp;
                temp++;
            }
            return factorial;
        }
        //采用递归法
        public static int recurrence(int num){
            if(num<=1)
                return 1;
            else
                return num*recurrence(num-1);
        }
    }

END

习题时间:

用递归方法完成以下题目---- 猴子吃桃问题

      猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。要求输入n(1<=n<=10),输出第n天有多少个桃子,当n==0时,输出猴子共有多少个桃子。

编辑:玥怡居士|审核:世外居士

往期精彩回顾

Java学习历程之----进阶篇(九)

Java学习历程之----进阶篇(八)

Java学习历程之----进阶篇(七)

扫码关注我们

IT进阶之旅

嗨,你还在看吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值