《算法和数据结构》从语言到算法的过渡篇_当语言学到什么程度可以开始学算法了(1)

《画解数据结构》(1 - 5)- 双端队列


6)哈希表

《画解数据结构》(1 - 6)- 哈希表

在这里插入图片描述


7)树

第二章

(2-1)画解树

、

更多内容请收看:画解树


8)二叉树

(2-2)画解二叉树

为了增加阅读体验,更多内容请收看:画解二叉树


9)二叉搜索树

《画解数据结构》(2 - 3)- 二叉搜索树


10)堆

(2-4)画解堆

为了增加阅读体验,更多内容请收看:画解堆


11)AVL树

(2-5)画解AVL树

本文已超五万字,为了增加阅读体验,更多内容请收看:画解二叉平衡树


12)线段树

(2-6)画解线段树

为了增加阅读体验,更多内容请收看:画解线段树


13)字典树

(2-7)画解字典树

在这里插入图片描述

为了增加阅读体验,更多内容请收看:画解字典树


14)霍夫曼树

(2-8)画解霍夫曼树

在这里插入图片描述

为了增加阅读体验,更多内容请收看:画解霍夫曼树


15)并查集

(2-9)画解并查集

为了增加阅读体验,更多内容请收看:画解并查集


16)图

第三章

(3-1)画解图

本文已超五万字,为了增加阅读体验,更多内容请收看:画解图


17)二分匹配

(3-2)画解二分匹配

为了增加阅读体验,更多内容请收看:画解二分匹配


18)最短路

(3-3)画解最短路

在这里插入图片描述

为了增加阅读体验,更多内容请收看:画解最短路


19)最小生成树

(3-4)画解最小生成树


   为了增加阅读体验,更多内容请收看:画解最小生成树


20)强连通

(3-5)画解强连通

为了增加阅读体验,更多内容请收看:画解强连通

4、算法入门

  • 算法入门,其实就是要开始我们的刷题之旅了。先给出思维导图,然后一一介绍入门十大算法。

🌌《算法入门指引》🌌

5、算法进阶

  • 算法进阶这块是我打算规划自己未来十年去完成的一个项目,囊括了 大学生ACM程序设计竞赛、高中生的OI竞赛、LeetCode 职场面试算法 的算法全集,也就是之前网络上比较有名的 《夜深人静写算法》 系列,这可以说是我自己对自己的一个要求和目标吧。
  • 如果只是想进大厂,那么 算法入门 已经足够了,不需要再来看算法进阶了,当然如果对算法有浓厚兴趣,也欢迎和我一起打卡。由于内容较难,工作也比较忙,所以学的也比较慢,一周基本也只能更新一篇。

这个系列主要分为以下几个大块内容:
  1)图论
  2)动态规划
  3)计算几何
  4)数论
  5)字符串匹配
  6)高级数据结构(课本上学不到的)
  7)杂项算法

  • 先来看下思维导图,然后我大致讲一下每一类算法各自的特点,以及学习方式:

在这里插入图片描述

1)图论

1、搜索概览
  • 图论主要围绕搜索算法进行展开。搜索算法的原理就是枚举。利用计算机的高性能,给出人类制定好的规则,枚举出所有可行的情况,找到可行解或者最优解。
  • 比较常见的搜索算法是 深度优先搜索(又叫深度优先遍历) 和 广度优先搜索(又叫广度优先遍历 或者 宽度优先遍历)。各种图论的算法基本都是依靠这两者进行展开的。
2、深度优先搜索
  • 深度优先搜索一般用来求可行解,利用剪枝进行优化,在树形结构的图上用处较多;而广度优先搜索一般用来求最优解,配合哈希表进行状态空间的标记,从而避免重复状态的计算;
  • 原则上,天下万物皆可搜,只是时间已惘然。搜索会有大量的重复状态出现,这里的状态和动态规划的状态是同一个概念,所以有时候很难分清到底是用搜索还是动态规划。
  • 但是,大体上还是有迹可循的,如果这个状态不能映射到数组被缓存下来,那么大概率就是需要用搜索来求解的。
  • 如图所示,代表的是一个深度优先搜索的例子,红色实箭头表示搜索路径,蓝色虚箭头表示回溯路径。
  • 红色块表示往下搜索,蓝色块表示往上回溯,遍历序列为:
	0 -> 1 -> 3 -> 4 -> 5 -> 2 -> 6

  • 同样,搜索的例子还有:
  • 计算的是利用递归实现的

n

n

n 的阶乘。

3、记忆化搜索
  • 对于斐波那契函数的求解,如下所示:
  • f

(

n

)

=

{

1

(

n

=

0

)

1

(

n

=

1

)

f

(

n

1

)

f

(

n

2

)

(

n

2

)

f(n) = \begin{cases}1 & (n = 0) \1 & (n = 1) \f(n-1) + f(n-2) & (n > 2) \end{cases}

f(n)=⎩⎪⎨⎪⎧​11f(n−1)+f(n−2)​(n=0)(n=1)(n>2)​

  • 对于

f

(

5

)

f(5)

f(5) 的求解,程序调用如下:
在这里插入图片描述

  • 这个过程用到了很多重复状态的搜索,我们需要将它优化,一般将一些状态缓存起来。
  • 我们通过一个动图来感受一下:
    在这里插入图片描述
  • 当第二次需要计算

f

(

2

)

f(2)

f(2) 和

f

(

3

)

f(3)

f(3) 时,由于结果已经计算出来并且存储在

h

[

2

]

h[2]

h[2] 和

h

[

3

]

h[3]

h[3] 中,所以上面这段代码的fib != inf表达式为真,直接返回,不再需要往下递归计算,这样就把原本的 “递归二叉树” 转换成了 “递归链”, 从而将原本指数级的算法变成了多项式级别。

  • 这就是记忆化搜索,像这种把状态缓存起来的方法,就是动态规划的思想了。
4、广度优先搜索
  • 单向广搜就是最简化情况下的广度优先搜索(Breadth First Search),以下简称为广搜。游戏开发过程中用到的比较广泛的 A* 寻路,就是广搜的加强版。
  • 我们通过一个动图来对广搜有一个初步的印象。

  • 从图中可以看出,广搜的本质还是暴力枚举。即对于每个当前位置,枚举四个相邻可以行走的方向进行不断尝试,直到找到目的地。有点像洪水爆发,从一个源头开始逐渐蔓延开来,直到所有可达的区域都被洪水灌溉,所以我们也把这种算法称为 FloodFill。
  • 那么,如何把它描述成程序的语言呢?这里需要用到一种数据结构 —— 队列。
  • 这时候,算法和数据结构就完美结合了。

2)动态规划

动态规划算法三要素:
  ①所有不同的子问题组成的表;
  ②解决问题的依赖关系可以看成是一个图;
  ③填充子问题的顺序(即对②的图进行拓扑排序,填充的过程称为状态转移);

  • 如果子问题的数目为

O

(

n

t

)

O(n^t)

O(nt),每个子问题需要用到

O

(

n

e

)

O(n^e)

O(ne) 个子问题的结果,那么我们称它为 tD/eD 的问题,于是可以总结出四类常用的动态规划方程:(下面会把opt作为取最优值的函数(一般取

m

i

n

min

min 或

m

a

x

max

max ),

w

(

j

,

i

)

w(j, i)

w(j,i)为一个实函数,其它变量都可以在常数时间计算出来)。

1、1D/1D
  • d

[

i

]

=

o

p

t

(

d

[

j

]

w

(

j

,

i

)

0

<

=

i

<

j

)

d[i] = opt( d[j] + w(j, i) | 0 <= i < j )

d[i]=opt(d[j]+w(j,i)∣0<=i<j)

  • 状态转移如图四所示(黄色块代表

d

[

i

]

d[i]

d[i],绿色块代表

d

[

j

]

d[j]

d[j]):

  • 这类状态转移方程一般出现在线性模型中。
2、2D/0D
  • d

[

i

]

[

j

]

=

o

p

t

(

d

[

i

1

]

[

j

]

x

i

,

d

[

i

]

[

j

1

]

y

j

,

d

[

i

1

]

[

j

1

]

z

i

j

)

d[i][j] = opt( d[i-1][j] + x_i, d[i][j-1] + y_j, d[i-1][j-1] + z_{ij} )

d[i][j]=opt(d[i−1][j]+xi​,d[i][j−1]+yj​,d[i−1][j−1]+zij​)

3、2D/1D
  • d

[

i

]

[

j

]

=

w

(

i

,

j

)

o

p

t

(

d

[

i

]

[

k

1

]

d

[

k

]

[

j

]

)

d[i][j] = w(i, j) + opt( d[i][k-1] + d[k][j] )

d[i][j]=w(i,j)+opt(d[i][k−1]+d[k][j])

  • 区间模型常用方程,如图所示:
    在这里插入图片描述
  • 另外一种常用的 2D/1D 的方程为:
  • d

[

i

]

[

j

]

=

o

p

t

(

d

[

i

1

]

[

k

]

w

(

i

,

j

,

k

)

k

<

j

)

d[i][j] = opt( d[i-1][k] + w(i, j, k) | k < j )

d[i][j]=opt(d[i−1][k]+w(i,j,k)∣k<j)

4、2D/2D
  • d

[

i

]

[

j

]

=

o

p

t

(

d

[

i

]

[

j

]

w

(

i

,

j

,

i

,

j

)

0

<

=

i

<

i

,

0

<

=

j

<

j

)

d[i][j] = opt( d[i’][j’] + w(i’, j’, i, j) | 0 <= i’ < i, 0 <= j’ < j)

d[i][j]=opt(d[i′][j′]+w(i′,j′,i,j)∣0<=i′<i,0<=j′<j)

  • 如图所示:
    在这里插入图片描述
  • 常见于二维的迷宫问题,由于复杂度比较大,所以一般配合数据结构优化,如线段树、树状数组等。
  • 对于一个tD/eD 的动态规划问题,在不经过任何优化的情况下,可以粗略得到一个时间复杂度是

O

(

n

t

e

)

O(n^ {t+e})

O(nt+e),空间复杂度是

O

(

n

t

)

O(n^t)

O(nt) 的算法,大多数情况下空间复杂度是很容易优化的,难点在于时间复杂度,后续章节将详细讲解各种情况下的动态规划优化算法。

3)计算几何

  • 计算几何的问题是代码量最大的。它是计算机科学的一个分支,以往的解析几何,是用代数的方法,建立坐标系去解决问题,但是很多时候需要付出一些代价,比如精度误差,而计算几何更多的是从几何角度,用向量的方法来尽量减少精度误差,例如:将除法转化为乘法、避免三角函数等近似运算 等等。
  • 如果一个比赛中,有一道计算几何的题,那么至少,它不会是一道水题。
1、double 代替 float
  • c++ 中 double 的精度高于 float,对精度要求较高的问题,务必采用 double;
2、浮点数判定
  • 由于浮点数(小数)中是有无理数的,即无限不循环小数,也就是小数点后的位数是无限的,在计算机存储的时候不可能全部存下来,一定是近似的存储的,所以浮点数一定是存在精度误差的(实际上,就算是有理数,也是存在误差的,这和计算机存储机制有关,这里不再展开,有兴趣可以参见我博客的文章:C++ 浮点数精度判定);
  • 两个浮点数是否相等,可以采用两数相减的绝对值小于某个精度来实现:
const double eps = 1e-8;
bool EQ(double a, double b) {
    return fabs(a - b) < eps;
}

  • 并且可以用一个三值函数来确定某个数是零、大于零还是小于零:
int threeValue(double d) {
    if (fabs(d) < eps)
        return 0;
    return d > 0 ? 1 : -1;
}

3、负零判定
  • 因为精度误差的存在,所以在输出的时候一定要注意,避免输出 -0.00:
    double v = -0.0000000001;
    printf("%.2lf\n", v);

  • 避免方法是先通过三值函数确定实际值是否为0,如果是0,则需要取完绝对值后再输出:
    double v = -0.0000000001;
    if(threeValue(v) == 0) {
        v = fabs(v);
    }
    printf("%.2lf\n", v);

4、避免三角函数、对数、开方、除法等
  • c++ 三角函数运算方法采用的是 CORDIC算法,一种利用迭代的方式进行求解的算法,其中还用到了开方运算,所以实际的算力消耗还是很大的,在实际求解问题的过程中,能够避免不用就尽量不用。
  • 除法运算会带来精度误差,所以能够转换成乘法的也尽量转换为乘法运算。
5、系统性的学习

基础知识:点、向量、叉乘、点乘、旋转、线段、线段判交、三角形面积;
进阶知识:多边形面积、凸多边形判定、点在多边形内判定;
相关算法:二维凸包、三维凸包、旋转卡壳、多边形面积交、多边形面积并、多边形面积异或、多边形和圆的面积交、半平面交、最小覆盖圆、最小包围球、模拟退火。

还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!

王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。

对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!

【完整版领取方式在文末!!】

93道网络安全面试题

内容实在太多,不一一截图了

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值