14天阅读挑战赛
努力是为了不平庸~
算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!欢迎记录下你的那些努力时刻(算法学习知识点/算法题解/遇到的算法bug/等等),在分享的同时加深对于算法的理解,同时吸收他人的奇思妙想,一起见证技术er的成长~
算法知识点
算法特性:
1.有穷性:算法是有若干条指令组成的有穷序列,总是在执行若干次后结束,不可能永不停止。
2.确定性:每条语句都有确定的含义,无歧义。
3.可行性:算法在当前环境条件下可以通过有限次运算来实现。
4.输入输出:有零个或多个输入以及一个或多个输出。
好的算法:
1.正确,2.易读,3.健壮,4.高效,5.低存储
常见的算法时间复杂度:
1.常数阶。运行次数为常数,用O(1)表示。
2.多项式阶。
通常用O(n),O(n^2),O(n^3)等表示。
3.指数阶。
运行效率极差,通常用O(2^n),O(n!),O(n^n)等表示。
4.对数阶。
运行效率较高,通常用O(logn),O(nlogn)等表示。
指数阶增量随着x的增加而急剧增加,而对数阶增长缓慢。它们之间的关系如下:
算法题目来源
zzulioj1055兔子繁殖问题
算法题目描述
题目描述
这是一个有趣的古典数学问题,著名意大利数学家Fibonacci曾提出一个问题:有一对小兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。按此规律,假设没有兔子死亡,第一个月有一对刚出生的小兔子,问第n个月有多少对兔子?
输入
输入月数n(1<=n<=44)。
输出
输出第n个月有多少对兔子。
样例输入
3样例输出
2
提示
本题是一个经典的递推入门题目: 用f(n)表示第n个月的兔子数目,则: f(n) = f(n-1) + 本月新生兔子数 而,本月新生兔子数 = f(n-2) (因为上上个月已存在的每只兔子,本月都会新生一只兔子) 所以,f(n) = f(n-1) + f(n-2) 这就是著名的fabinacci数列,后一项等于前两项的和: 1 1 2 3 5 8.....
做题思路
不难发现兔子数从第三个月开始的规律是该月兔子数等于上一个月兔子数加上上月的兔子数
模板代码
1.递归算法
int nums(int n) {
if(n==1||n==2){
return 1;
}
else
return nums(n-1)+nums(n-2);
}//递归
不难看出是一个指数阶的算法,在算法设计中应当避开。
2.使用数组记录前两个月的兔子数并对其进行加法运算。
int nums(int n) {
int *F=new int [n+1];
F[1]=F[2]=1;
for(int i=3;i<=n;i++){
F[i]=F[i-1]+F[i-2];
}
return F[n];
}
该算法的时间复杂度为O(n),由指数阶降到了多项式阶。
使用了辅助数组记录中间结果,空间复杂度也为O(n),实际上中间结果只是为了下一次使用,不需要记录,因此可以使用迭代法进行算法设计。
int nums(int n) {
if(n==1||n==2){
return 1;
}
int x=1,y=1,t;
for(int i=3;i<=n;i++){
t=x+y;
x=y;
y=t;
}
return t;
}
时间复杂度依然是O(n),但空间复杂度降到了常数阶。