一、递归
递归就是将一个问题拆解成解决方案完全相同的子问题,并且有一个明确的终点
从哪来到哪去 D运行结束回到C 然后回到B然后回到A
1.斐波那契数列
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契,以兔子繁殖为例子而引入,故又称“兔子数列”,其数值为:1、1、2、3、5、8、13、21、34、55……在数学上,这一数列以如下递推的方法定义:F(0)=1,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。
解法一:递归
#include<stdio.h>
unsigned int FB(unsigned int n)
{
if(n==0)return 0;
if(n==1||n==2)return 1;
return FB(n-1)+FB(n-2);
}
int main()
{
unsigned int fb = FB(40);
printf("%u\n",fb);
return 0;
}
解法二:优化后的
即在原本的基础上 对上一次的运算结果进行一个存储 防止再次重复计算
#include<stdio.h>
unsigned int FB2(unsigned int n)
{
if(n==0)return 0;
if(n==1||n==2)return 1;
int a=1,b=1,c=0;
for(int i=3;i<=n;i++)
{
c=a+b;
a=b;
b=c;
}
return c;
}
int main()
{
unsigned int fb = FB2(40);
printf("%u\n",fb);
return 0;
}
解法三:矩阵
2.跳台阶问题
其实跟斐波那契数列是一个问题 就是初值有所不同
class Solution {
public:
int numWays(int n) {
if(n==0||n==1){
return 1;
}
if(n==2)
{
return 2;
}
int a=1,b=2,c=0;
for(int i=3;i<=n;i++)
{
c=(a+b)%1000000007;//答案需要取模 1e9+7(1000000007)
a=b;
b=c;
}
return c;
}
};
3.汉诺塔问题
这个问题来源于印度。有三个金刚石塔,第一个从小到大摞着64片黄金圆盘。现在把圆盘按大小顺序重新摆放在最后一个塔上。并且规定,在小圆盘上不能放大圆盘,在三个塔之间一次只能移动一个圆盘。
二、分治
分治法:分而治之 将一个问题拆解成若干个解决方法相同的子问题
分治法需要满足四点:
- 问题难度随着数据规模缩小而降低
- 问题可拆分
- 子问题之间相互独立
- 子问题的解可以合并
2.二分查找 BinaryChop
折半搜索,首先的要求就是 有序,
方法步骤为
- 先找到中间元素mid
- 让mid与要寻找的值target进行比较
- 如果mid>target那么搜索范围就变成(Begin,Mid-1)
- 如果mid<target那么搜索范围就变成(Mid+1,End)
-
int BinaryChop(int arr[],int nBegin,int nEnd,int target) { if(arr==NULL||nBegin>nEnd)return -1; int nMid; while(nBegin<nEnd) { nMid=nBegin+(mEnd-nBegin)/2; if(arr[nMid]==target) { return nMid; } else if(arr[nMid]>target) { nEnd=nMid-1; } else { nBegin=nMid+1; } } return -1; }
int BinaryChop(int arr[],int nBegin,int nEnd,int target) { if(arr==NULL||nBegin>nEnd)return -1; int nMid=nBegin+(nEnd-nBegin)/2; if(arr[nMid]==target) { return nMid; } else if(arr[nMid]>target) { return BinaryChop(arr,nBegin,nMid-1,target); } else { return BinaryChop(arr,nMid+1,nEnd,target); } }