千禧难题之一:
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时,输出猴子共有多少个桃子。
编辑:玥怡居士|审核:世外居士
▼
往期精彩回顾
▼
扫码关注我们
IT进阶之旅
嗨,你还在看吗?