《8分钟讲懂一个算法》观看笔记

一、算法的意义

《8分钟讲懂一个算法》观看笔记_第1张图片

例子:

《8分钟讲懂一个算法》观看笔记_第2张图片

《8分钟讲懂一个算法》观看笔记_第3张图片

《8分钟讲懂一个算法》观看笔记_第4张图片

三、时间复杂度与大O表示法

《8分钟讲懂一个算法》观看笔记_第5张图片
越往左边,算法越好。

四、算法分析法则及其他渐进符号

法则1 for循环

《8分钟讲懂一个算法》观看笔记_第6张图片

法则2 嵌套的for循环

《8分钟讲懂一个算法》观看笔记_第7张图片

法则1的扩展,由内而外的计算复杂度

法则3 顺序语句

《8分钟讲懂一个算法》观看笔记_第8张图片

简单概括,谁大听谁的。

法则4 if/else语句

《8分钟讲懂一个算法》观看笔记_第9张图片

一些渐进符号

《8分钟讲懂一个算法》观看笔记_第10张图片

大O:一般用来表示最坏复杂度,有明确的边界上界
大Ω:最优复杂度,有下界
大θ(theta):西塔表示法,同时描述了 复杂度的上界和下界,总结概括起来就是,只有当大O等于大Ω的时候,才会存在θ
小o:没有上界
小ω:最优复杂度,没有下界。

五、二分法查找

《8分钟讲懂一个算法》观看笔记_第11张图片

时间复杂度:

《8分钟讲懂一个算法》观看笔记_第12张图片

算法步骤:
《8分钟讲懂一个算法》观看笔记_第13张图片

注意事项:
(1)先决条件:有序数组
(2)注意数据类型是有范围的,采用 L+(R - L)/ 2 表达式更合适
(3)注意 start = mid + 1 和 end = mid -1 ,防止死循环
(4)数据量不可过大

常见面试题变种:
1.查找第一个/最后一个与target相等的元素
2.查找最后一个小于target/第一个大于target的元素
3.查找最后一个小于等于target/第一个大于等于target的元素
4.数组的旋转 (4,5,6,1,2,3)

六、数组vs链表

时间复杂度

《8分钟讲懂一个算法》观看笔记_第14张图片

《8分钟讲懂一个算法》观看笔记_第15张图片

七、顺序表

1.线性表概述

《8分钟讲懂一个算法》观看笔记_第16张图片

线性表 -> 顺序表 -> 数组 ,是从属关系。

在程序中,我们经常要将一组元素作为一个整体来管理使用。对于这种需求,最简单的办法,便是把它们看成一个序列。一但一个数据被添加,它相对于前后元素就一直保持着该位置不变。这样的组织形式,我们将其抽象为线性表。

线性表有两端,可以称为前后或左右也行,当然也可以称为顶部和底部。其实,表达的意思基本一样。总之,线性表每个元素都有前后顺序,它们具有线性逻辑。与线性表对应的,当然就是非线性表,比如树,比如图,等等。

顺序表是在计算机内存中用一组地址连续的存储单元依次存储数据元素的线性数据结构,大家需要注意,我们这里要求地址连续。数组以及数组衍生出去的数据结构都属于顺序表。其中我们在C语言以及Java中,最常见的顺序表应该是数组。

2.顺序表

【数组】

数组的元素的位置我们称之为:索引。
利用元素的索引可以计算出该元素对应的存储地址。

索引是从0开始,而不是我们生活中习惯的1开始。
(如果我们把索引理解为对数组起始位置的偏移量,可能对此会更好理解一些。第一个元素相对于数组起始位置偏移了0,所以索引是0,第二个元素偏移了1,所以索引是1。当然,这也有其历史原因,当初IBM一统天下,索引从0开始的话,处理器可以直接进行指针偏移计算,编译效率是很高的。例如,对于数组,指针是P,那么第一个元素的指针就是P+0,索引为n的元素,指针为 P+n,这个习惯从B语言一路到C语言、Java等。 )

数组支持随机访问

【引用数组】

【动态数组】

ArrayList(Java)

八、链表

1.单链表

《8分钟讲懂一个算法》观看笔记_第17张图片

2.双向链表

克服单向链表不对称的特性。

《8分钟讲懂一个算法》观看笔记_第18张图片

3.循环链表

《8分钟讲懂一个算法》观看笔记_第19张图片

4.常见面试题目

《8分钟讲懂一个算法》观看笔记_第20张图片

九、栈&队列

栈:先进后出(FILO)

队列:先进先出(FIFO)

1.栈

基于栈的操作:push、pop、top()、is_empty()、length()

操作系统在管理函数的参数以及局部变量的内容时,采用的就是类似于栈的结构:
《8分钟讲懂一个算法》观看笔记_第21张图片

栈可以用顺序表来实现,也可以用链表来实现。

2.队列

基于队列的操作:在队尾插入元素、取出第一个元素、判断是否为空、获取长度

循环队列

双端队列:

《8分钟讲懂一个算法》观看笔记_第22张图片

栈和队列常见考题

  1. 栈和队列的实现,包括数组和链表的两种形式
  2. 两个栈实现一个队列,两个队列实现一个栈
  3. 要求实现一个栈,Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1)
  4. 括号的匹配
  5. 前缀、中缀、后缀表达式求值

十、初级排序(选择 冒泡 插入 希尔)

对排序算法的学习和分析有助于你理解其他算法。
类似的技术可能有效解决其他类型的问题。
排序算法通常是我们解决其他问题的第一步。

1.选择排序

《8分钟讲懂一个算法》观看笔记_第23张图片

遍历第一遍找到最小元素与第一个位置元素交换;遍历剩下元素找到最小值 与 第二个位置元素交换 ; 依次类推

时间复杂度:O(n²)
空间复杂度:O(1)

运行时间和输入无关
数据移动是最少的

2.冒泡排序

《8分钟讲懂一个算法》观看笔记_第24张图片

从1到n的位置,相邻两个元素进行比较,如果后面元素值小则与前面元素交换位置,依次类推。
第一遍遍历完后得到第n个位置的值是最大的,接着遍历 1到n-1 ,依次类推。

时间复杂度:O(n²)

3.插入排序

《8分钟讲懂一个算法》观看笔记_第25张图片

首先取出第一个元素,认为已经排好序了。取出第二个元素与第一个元素比较,若比其小交换位置。
取出第三个元素,与第一、第二个元素比较。依次类推。

类似扑克牌的整理。

特点:
数组中每个元素距离它的最终位置都不远。
一个有序的大数组接一个小数组。
数组中只有几个元素的位置不正确。

总结:基于以上思路,插入排序可能比前面几种排序都快。并且基于插入排序进行优化,得到了希尔排序。

4.希尔排序

希尔排序的核心思想
将待排序序列划分为若干组,在每一组内进行插入排序,让元素可以一次性的朝最终位置前进一大步,以使整个序列基本有序,然后再对整个序列进行插入排序。算法的最后一步就是普通的插入排序,但是这个时候,需要排序的数据几乎是已经拍好的了,所以会非常高效。

演示
《8分钟讲懂一个算法》观看笔记_第26张图片

步长采用3H+1。即1、4、13。
第一次步长13,因为13后只有两个数14和5所以只比较了两个数;
第二次步长为4,每个小数组在交换比较;
第三次步长为1,就是一次插入排序。

特点
各个子数组都很短。
排序之后子数组都是部分有序的。

时间复杂度
最坏时间复杂度:根据步长序列不同而不同,目前已知最好的是 O(nlogn)
最有时间复杂度:O(n)

十一、归并排序

据说冯诺依曼发明,用了分治思想。

在计算机科学中,分治法是一种很重要的算法思想。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题…直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,比如接下来要讲的归并排序和快速排序,还有快速傅里叶变换等等…

你可能感兴趣的:(笔记)