递归
程序调用自身的编程技巧称为递归
public static void show(){
show();
}
它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
递归前进段
边界条件
递归返回段
分治算法
分治算法就是将原问题划分成n个规模较小,并且结构与原问题相似的子问题,递归地解决这些子问题,然后在合并其结果,就得到原问题的解。
分治算法的递归实现中,每一层递归都会涉及这样三个操作:
- 分解:将原问题分解成一系列子问题。
- 解决:递归地求解各个子问题,若子问题足够小,则直接求解。
- 合并:将子问题的结果合并成原问题。
分治算法能解决的问题,一般需要满足下面这几个条件:
- 原问题与分解成的小问题具有相同的模式
- 原问题分解成的子问题可以独立求解,子问题之间没有相关性
- 具有分解终止条件,也就是说,当问题足够小,可以直接求解
- 可以将子问题合并成原问题,而这个合并操作的复杂度不能太高,否则就起不到减小算法总体复杂度的效果了。
另外:
- 但凡能够用数学归纳法解决的问题,都可以使用分治思想
- 分治思想不一定使用递归结构
范例:前n项求和问题
public class Recursion {
public static void main(String[] args) {
//递归累加 O(n)
test01();
//迭代累加 O(n)
test02();
}
private static void test02() {
int sum=0;
int n=100;
for (int i=0;i<=n;i++){
sum+=i;
}
System.out.println(sum);
}
private static void test01() {
int n=100;
int sum=sum(n);
System.out.println(sum);
}
private static int sum(int n) {
if(n==1){
return 1;
}
return sum(n-1)+n;
}
}
执行结果
5050
5050
范例:n的阶乘问题
public class Recursion02 {
public static void main(String[] args) {
//递归阶乘
test01(); //O(n)
//迭代阶乘
test02();//O(n)
}
private static void test02() {
int n=10;
int product=1;
for (int i=1;i<=n;i++){
product*=i;
}
System.out.println(product);
}
private static void test01() {
int n=10;
int product=factorial(n);
System.out.println(product);
}
private static int factorial(int n) {
if(n==1){
return 1;
}
return factorial(n-1)*n;
}
}
执行结果
3628800
3628800
范例:斐波那契数列问题
public class Recursion03 {
public static void main(String[] args) {
//递归斐波那契数列 O(2^n)
test01();
//迭代斐波那契数列 O(n)
test02();
}
private static void test02() {
int n=45;
int num=getFabonacci(n);
System.out.println(num);
}
private static int getFabonacci(int n) {
if (n==1||n==2){
return 1;
}
int first=1;
int second=1;
int current=0;
for (int i=3;i<=n;i++){
current=first+second;
first=second;
second=current;
}
return current;
}
private static void test01() {
int n=5;
int num=fabonacci(n);
System.out.println(num);
}
private static int fabonacci(int n) {
if (n==1||n==2){
return 1;
}
return fabonacci(n-1)+fabonacci(n-2);
}
}
执行结果
5
1134903170