牛客网视频总结1
开始刷题看视频!小孙95%的概率准备找工作啦!准备上!视频无法上传啦,就写一点我自己总结的东西吧,一是提醒自己好翻阅,二是希望能够帮助到其他找工作的小伙伴吖~
时间复杂度
时间复杂度为一个算法流程中,常数操作数量的指标。常用O来表示。具体来说,在常数操作数量的表达式中,只要高阶项,不要低阶项,也不要高阶项的系数,剩下的部分如果记为f(N),那么时间复杂度为O(f(N))。
举例子:有序数组A,大小为N;无序数组B,大小为M,在A中找B里的元素,计算一下三种方法的时间复杂度
- 遍历,复杂度O(M*N)
- 2分法,复杂度O(MlogN)
- 先排序+外排法(指针后移),复杂度O(M*logM)+O(M+N)
结论:相比较而言,1不行,但是2.3谁更好这无法确定,要看具体M和N的数值
排序问题
冒泡排序
两两比较,先确定大的,代码在最后一部分的图片里
- 比较相邻的两个数,如果第一个数比第二个数大,则两数交换
- 对之后的相邻元素进行同样的工作,从开始到最后一对,这样进行一次排序后,最后一位会是最大值 ,第一次循环进行的次数为 arr.length-1
- 之后对所有的元素重复以上的步骤
- 重复上述步骤,直到排序完成
结论:时间复杂度 O ( N 2 ) O(N^2) O(N2),为N+N-1+N-2+…+2+1
选择排序
直接遍历,先确定小的,代码在最后一部分的图片里
- 在一个长度为 N 的无序数组中,第一次遍历 n-1 个数找到最小的和第一个数交换。
- 第二次从下一个数开始遍历 n-2 个数,找到最小的数和第二个数交换。
- 重复以上操作直到第 n-1 次遍历最小的数和第 n-1 个数交换,排序完成。
结论:时间复杂度为 O ( N 2 ) O(N^2) O(N2),为N+N-1+N-2+…+2+1
插入排序
插入排序的基本思想是将一个元素插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动
- 先看前两个,进行比较排序
- 看第三个,先和第二个比较,交换的话再往前比较;不交换不比较前面的
- 看第四个,先和第三个比较,…
- 一直到最后一个
结论:最好情况也就是本身就是正序数组时间复杂度 O ( N ) O(N) O(N),最差情况为逆序数组时间复杂度 O ( N 2 ) O(N^2) O(N2),一般说时间复杂度都说最差的情况
归并排序
算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。
- 分解(Divide):将n个元素分成个含n/2个元素的子序列。
- 解决(Conquer):用合并排序法对两个子序列递归的排序。
- 合并(Combine):合并两个已排序的子序列已得到排序结果。
如何将两个有序数列合并成一个有序数列?
答:外排法——由于两个数列都已经有序,我们只需从两个数列的低位轮番拿出各自最小的数来PK就就行了,输的一方为小值,将这个值放入临时数列,然后输的一方继续拿出一个值来PK,直至有一方没有元素后,将另一方的所有元素依次接在临时数列后面即可。此时,临时数列为两个数列的有序合并。
结论:时间复杂度
O
(
N
l
o
g
N
)
O(NlogN)
O(NlogN),因为外排法为
O
(
N
)
O(N)
O(N),前半部分分为了2半,
T
(
N
)
=
2
T
(
N
/
2
)
+
O
(
N
)
T(N)=2T(N/2)+O(N)
T(N)=2T(N/2)+O(N),此时
l
o
g
b
a
=
d
log_ba=d
logba=d,因此时间复杂度为
O
(
N
d
∗
l
o
g
N
)
O(N^d*logN)
O(Nd∗logN)
递归
递归有以下两个特点:
- 一个问题可以分解成具有相同解决思路的子问题,子子问题,换句话说这些问题都能调用同一个函数
- 经过层层分解的子问题最后一定是有一个不能再分解的固定值的(即终止条件),如果没有的话,就无穷无尽地分解子问题了,问题显然是无解的。
递归复杂度通式:
T
(
N
)
=
a
T
(
N
/
b
)
+
O
(
N
d
)
T(N)=aT(N/b)+O(N^d)
T(N)=aT(N/b)+O(Nd)
a为子过程次数,b为子过程样本量,最后一项代表除子过程以外的剩下过程的复杂度
当
l
o
g
b
a
>
d
log_ba>d
logba>d时,复杂度为
O
(
N
l
o
g
b
a
)
O(N^{log_ba})
O(Nlogba)
当
l
o
g
b
a
=
d
log_ba=d
logba=d时,复杂度为
O
(
N
d
l
o
g
N
)
O(N^dlogN)
O(NdlogN)
当
l
o
g
b
a
<
d
log_ba<d
logba<d时,复杂度为
O
(
N
d
)
O(N^d)
O(Nd)
对数器
简单来说,对于任意一个问题,我们一般都会有至少两种不同的解法,也就是一个想起来很简单,并且完全正确但是运行效率较低的解法和一个不容易想到,正确性未知但是运行效率比较高的解法,而我们要用的对数器,就是让同样的随机测试用例,用两种算法来跑,当测试用例非常大时(例如500000组),如果两组算法得出的结果相同,那我们就有理由认为我们想出的新解法是完全正确的。
因此对数器需要两个基本条件:
- 产生随机样本的产生器
- 绝对正确的方法(复杂度高但易实现)
例题:小和计算
在一个数组里,每一个数左边比当前数小的数累加起来,叫做这个数组的小和,求一个数组的小和问题,见图片。
详细笔记