每日算法
2020-07-05
最多需要猜测的次数与列表长度相同,这被称为线性时间(linear time)
二分查找的运行时间为对数时间(或log时间)
大O表示法:指出了算法的速度有多快(最糟糕的情况);运算时间为O(n),并非以秒为单位的速度,只是能够比较操作数,指出了算法运行时间的增速。
例如:有10亿个元素时,二分查找需要大约30毫秒,二分为简单查找的15倍 ,所以 简单查找为100毫秒。
可实际上,简单查找需要10亿毫秒,相当于11天。因为二分查找 和 简单查找的运算时间和增速不同
O(log n);对数时间 二分查找
O(n); 线性时间 简单查找
O(n * log n); 快速排序
O(n²); 选择排序
O(n! ); 这个非常慢。。。n的阶乘 例如:要去5个城市,规划出最短路线。。。

算法的速度指的并非时间,而是操作数的增速!
二分查找:O(log n);对数时间
log232 = 5;(log以2为低,32的对数);
python:binary_search函数接受一个有序数组和一个元素。如果指定的元素包含在数组中,就返回其位置(下标index)

2020-07-08 时间真是挤出来的(月亮不睡我不睡)
选择排序:
数据存储两种基本方式:数组和链表

一般选择混合排序:链表数组。。。


选择排序需要的总时间为O(n x n),即O(n²)
?:每次检索不是会少1吗,应该是O(n x 1/2 x n)。
但大O表示法省略1/2这样的常数~
查找最小值:


递归:
效率不怎么滴,指示方便理解。盒子里找钥匙的伪代码:

每个递归函数都有两部分:
基线条件(base case) 和 递归条件(recursive case)
递归条件指的是函数调用自己,
而基线条件则指的是函数不再调用自己,从而避免形成无限循环

栈(call stack):
递归调用栈,所以 1.循环替换递归 2.使用尾递归


简单的理解:
将可能返回的结果作为下次递归的参数传入
快速排序:
其运行时间为:O(n log n)
分而治之(divide and conquer , D&C):
D&C算法是递归的,主要2个步骤:
1.找出基线条件,这种条件必须尽可能简单
2.不断将问题分解(缩小规模),直到符合基线条件
将一块 矩形 土地分为 n块大小相同的正方形:
首先:欧几里得算法
gcd(a,b) = gcd(b,a mod b);(困了,先睡了)
2020-7-10:
论证欧几里得算法:
gcd(a,b)=gcd(b,a mod b)
假设 c=gcd(a,b) //c为a,b的最大公约数
则存在 m,n 使 a=mc,b=nc
令 r = a mod b //r为 a,b的余数
即存在 k 使 r = a - kb = mc - knc = (m - kn)c
故 gcd(b,a mod b) = gcd(b,r) = gcd(nc , (m - kn)c) = gcd(n , (m - kn))c //则 c 为 b , a除以b的余数 的最大公约数
//因 c 为 n,(m-kn)的公约数 ; c 为(m-kn)的最大公约数
假设 d=gcd(n,m-kn) ,则存在x,y,使 n=xd, m-kn=yd
因 m-kn=yd 故 m=yd+kn ; 因 n=xd 故 m=yd+kxd=(y+kx)d
故有 a = mc = (y+kx)dc, b = nc = xdc;
可得 gcd(a,b) = gcd((y+kx)dc,xdc) = gcd((y+kx),x)dc //则 dc 为 a , b 的最大公约数
因 gcd(a,b) = c ; 故 dc = c ; 即 d = 1;
即 gcd(n,m-kn) = 1;
即 gcd(b,a mod b) = gcd(n , (m - kn))c = 1 ✖️c = c;
得出结论:a,b的最大公约数 等于 (b与(a除以b的余数) 的最大约数)
所以将一块 矩形 土地分为 n块大小相同的正方形时,
可以 先去掉和 短边 一样长度 正方形,
剩下的面积同理,直到剩余图形为矩形~


D&C的工作原理:
1.找出简单的基线条件;
2.确定如何缩小问题的规模,使其符合基线条件
求数组 arr[2,4,6] 的元素总和:
1.基线条件:

2.缩小规模:


这样就缩小了规模~

使用递归
(为啥不用循环?请了解下Haskell,不是所有语言都有循环~这语言值得一学~虽然我不会~)
快速排序:
其运行时间为:O(n log n)
1.基线条件 length<2 当数组只有1个或没有元素时,直接return
2.缩小规模:
首先从数组选择一个元素,这个元素被称为 基准值(pivot)
接着,找比 基准值 小的元素以及比 基准值 大的 元素
这个操作叫做 :分区(partitioning)
现在就拥有了
1.一个所有元素小于基准值的子数组
2.一个所有元素大于基准值的子数组
3.基准值
这里只是分区,数组还是无序的(如果有序,直接return 1+3+2)
接着对子数组进行快速排序
归纳证明:
归纳证明是一种证明算法行之有效的方式,
分两步:基线条件和归纳条件

合并排序:
运行 时间为O(n log n)
实际上n是 c*n
c是固定的时间量,被称为常量
对于快速排序,高度依赖于基准值
可分为:平均情况 和 最糟情况
最糟为O(n) 最佳为O(log n)

浙公网安备 33010602011771号