当“人工智能”、“AlphaGo”、“无人驾驶”、“智能投顾”等词语不断在人们视野中出现的时候,意味着我们正步入一个算法的时代。计算机通过提供给人类每天要面临的各种选择的最优解,从而让我们能更加高效的生活在这个信息爆炸的时代。
而对于大多数非算法专业领域的程序员来说,也逐渐意识到了算法的重要性。学习算法,从而更好的应用算法,通过算法去优化代码,提高程序效率。
什么是算法
- 快速排序算法
- 最排序算法
- 归并排序
- 二分查找算法
- BFPRT(线性查找算法)
- DFS(深度优化算法)
- BFS(过度优化搜索)
- Dijkstra算法
- 动态规划算法
- 朴素贝叶斯分类算法
算法的英文名称是Algorithm,这个词在1957年之前在Webster’s New World Dictionary(《韦氏新世界词典》)中还未出现,只能找到带有它的古代涵义的较老形式的“Algorism”(算术),是指用阿拉伯数字进行算术运算的过程。在中世纪时,珠算家用算盘进行计算,而算术家用算术进行计算。
根据经验和发展结论得出,算法应该具有如下五个重要的特征。
- 有穷性:保证执行有限步骤之后结束;
- 确切性:每一步骤都有确切的定义;
- 输入:每个算法有零个或多个输入,以刻画运算对象的初始情况,所谓零个输入是指算法本身定除了初始条件;
- 输出:每个算法有一个或多个输出,显示对输入数据加工后的结果。没有输出的算法是毫无意义的;
- 可行性:在原则上算法能够精确地运行,进行有限次运算后即可完成一种运算。
算法的时间复杂度和空间复杂度合称为算法的复杂度。
一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。
一个程序的空间复杂度是指运行完一个程序所需内存的大小。利用程序的空间复杂度,可以对程序的运行所需要的内存多少有个预先估计。
对称加密算法 (Symmetric-key algorithm) 和非对称加密算法 (asymmetric key encryption algorithm) 只不过就是密码学 (encryption) 中的两种解密算法罢了,什么是算法,你就可以理解成为是一种规则吧,这种规则可以将信息从一种形式转变成另一种形式
《算法新解》作者刘新宇:我只是想打开那些黑盒子,告诉人们里面有什么。
他七年磨一剑,笔耕不辍,写成《算法新解》一书。
《算法新解》总共分4部分——树、堆、队列和序列、排列和搜索,用函数式和传统方法介绍主要的基本算法和数据结构,数据结构部分包括二叉树、红黑树、AVL树、Trie、Patricia、后缀树、B树、二叉堆、二项式堆、斐波那契堆、配对堆、队列、序列等;基本算法部分包括各种排序算法、序列搜索算法、字符串匹配算法(KMP等)、深度优先与广度优先搜索算法、贪心算法以及动态规划。
算法与数据结构
如果说,熟练掌握编程语言是外功,那么数据结构可谓是内功心法了
- 抽象数据类型(ADT)的物理实现
- “数据结构”是计算机中存储,组织数据的方式。
- “数据结构是数据对象”以及存在于该对象的实例和组成实例的数据元素之间的各种联系
- 解决问题方法的效率跟数据的组织方式、空间的利用效率和算法的巧妙程度有关
本系列将采用Java语言来进行描述。亦即总结常见的的数据结构,以及在Java中相应的实现方法,务求理论与实践一步总结到位。
链表一种常见的数据结构,可以存储有序的元素集合。不同于数组,链表中元素在内存中不是连续放置,同时每一个链表元素中除了本身的节点还保存了指向下一个元素的引用,这些特点使得链表元素在动态增加和删除时不必移动其他元素,但是访问链表元素时必须从起点开始迭代列表直到找到目标元素。
单链表经常为公司面试所提及,先不贬其过于简单,因为单链表确实是数据结构中最简单的一部分,但往往最简单的,人们越无法把握其细节。
本文一共总结了单链表常被提及的各种操作,如下:
- 逆序构造单链表;
- 链表反转;
- 链表排序;
- 合并两个有序链表;
- 求出链表倒数第k个值;
- 判断链表是否有环,有环返回相遇节点;
- 在一个有环链表中找到环的入口;
- 删除当前节点;
- 找出链表的中间节点。
JS 数据结构和算法
数据结构就是关系,没错,就是数据元素相互之间存在的一种或多种特定关系的集合。
传统上,我们把数据结构分为逻辑结构和物理结构。
- 逻辑结构:是指数据对象中数据元素之间的相互关系,也是我们今后最需要关注和讨论的问题。
- 物理结构:是指数据的逻辑结构在计算机中的存储形式。
栈和队列都是动态的集合,在栈中,可以去掉的元素是最近插入的哪一个。栈实现了后进先出。在队列中,可以去掉的元素总是在集合中存在的时间最长的那一个。队列实现了先进先出的策略。
二叉树(Binary Tree)是n(n>=0)个结点的有限集合,该集合或者为空集(空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。
字典是以键值对形式存储数据的数据结构,就像电话号码薄里的名字和电话号码那样的一一对应的关系。
javascript
的Object
类就是以这样的一种字典形式设计的。
算法学习
算法虐我千百遍,我待算法如初恋。这里的内容是我学习算法过程的一些记录,希望能一直坚持下去。
学习方法
- 把所有经典算法写一遍
- 看算法有关源码
- 加入算法学习社区,相互鼓励学习
- 看经典书籍
- 刷题
算法深入研究
所谓神经网络是一组连接的输入/输出单元,类似于人脑中的神经细胞,其中每个连接都与一个权重相关联。学习阶段通过输入元组,不断的调整权重参数,使得它能够预测输入元组的正确类标号。
所谓类标号,是某种类别的标号。
MD5 和 SHA 系列算法都属于同一类——我还没给这类算法找到一个足够贴切的名字。首先在大的分类上,它们都是散列算法。
散列是怎么个定义呢?典型的散列算法可以是任何一个:具有无限的定义域,且具有有限的值域的函数。甚至,宽松的广义散列算法可以是任何一个(数学意义上的)函数,因为函数本身的概念就是将一个或多个值映射到一个唯一的值。
红黑树是在实际工程中被广泛应用的一种数据结构,比如Linux中的线程调度就是使用的红黑树来管理进程控制块,而Nginx中也是使用红黑树来管理的timer,Java中的TreeMap和TreeSet也是基于红黑树来实现的。
红黑树相比普通二叉查找树的一个优势就是它的树高为~lgN,所以不管是查找/插入/删除操作它均能保证能够在对数时间之内完成。本文我们就先来了解一下红黑树插入算法的实现。
二叉查找树是一种能将链表插入的灵活性和有序数组查找的高效性结合起来的一种重要的数据结构,它是我们后面学习红黑树和AVL树的基础,本文我们就先来看一下二叉查找树的实现原理。
设计算法时使用递归的思想是一个程序员的基本素质,递归可以把一个很庞大的问题转化为规模缩小了的同类问题的子问题,通过这一思想,我们编程时运用递归可以使用很少的代码来处理很大的问题。这篇文章将会讲到递归算法的运用。
今年过年微信红包成了全民焦点,虽然大多数的红包就一块八角的样子,还是搞得大家乐此不彼地,蛋爷我年三十晚什么都没干就守在手机旁边不是摇手机红包就是抢群红包。作为一名程序猿,自然会想了解下红包的实现细节。我在网上谷歌了下,微信目前是没有公布红包的实现细节的,所以这里就提出一个自己的方案。
四种重要的图模型:
- 无向图(简单连接)
- 有向图(连接有方向性)
- 加权图(连接带有权值)
- 加权有向图(连接既有方向性又带有权值)
一致性哈希算法 CARP 原理解析, 附 Golang 实现
在后端服务开发的过程中, 遇到了这样一个问题: 需要在 mysql 前面部署 redis 做一层缓存,要求 redis 是集群部署, 并且每台 redis 节点只缓存总数据量的 1/N, N 为 redis 的个数。
动态规划常用于最优化问题。可能存在多个取最优解的值,希望找到其中一个最优解。
动态规划的设计分为以下四个步骤:
- 描述最优解结构
- 递归定义最优解的值
- 按自底向上的方式计算最优解的值
- 由计算出的结果构造一个最优解
PHP基础算法
机器学习中的算法
[干货]什么是机器学习?基础机器学习算法
哲学要回答的基本问题是从哪里来、我是谁、到哪里去,寻找答案的过程或许可以借鉴机器学习的套路:组织数据->挖掘知识->预测未来。组织数据即为设计特征,生成满足特定格式要求的样本,挖掘知识即建模,而预测未来就是对模型的应用。
整体上看,机器学习就是模仿人识别事物的过程,即:学习、提取特征、识别、分类。由于机器不能跟人类思维一样根据事物特征自然而然的选择分类方法,所以机器学习方法的选择依然还需要人工选择。
机器学习方法非常多,也很成熟。
- SVM
- KNN
- Naive Bayes
- 回归
- 决策树
KNN是k-Nearest-Neighbours的缩写,它是一种监督学习算法。KNN算法可以用来做分类,也可以用来解决回归问题。
简单地说,KNN算法由那离自己最近的K个点来投票决定待分类数据归为哪一类。
利用KNN的具体步骤:
-计算上述图中所有点到达待测点的欧式距离(勾股定理计算)。
-选出离待测点最近的K个点,k由用户指定。
-计算在这k个点中,各个类型的个数
-将个数最多的类型作为预测点的类型。
在机器学习中,聚类算法是一种无监督分类算法。聚类算法很多,包括基于划分的聚类算法(如:kmeans),基于层次的聚类算法(如:BIRCH),基于密度的聚类算法(如:DBScan),基于网格的聚类算法等等。
基于划分和层次聚类方法都无法发现非凸面形状的簇,真正能有效发现任意形状簇的算法是基于密度的算法,但基于密度的算法一般时间复杂度较高,1996年到2000年间,研究数据挖掘的学者们提出了大量基于网格的聚类算法,网格方法可以有效减少算法的计算复杂度,且同样对密度参数敏感。
算法与加密
本文整理了常见的安全算法,包括MD5、SHA、DES、AES、RSA等,并写了完整的工具类(Java 版),工具类包含测试。
Java 加密算法
密码学基本功能:机密性、鉴别、报文完整性、不可否认性
JAVA加密算法(2)- 消息摘要算法(MD5、SHA、HMAC)
对消息通过一个单向Hash算法进行计算,得到一个唯一的结果。每个消息对应一个唯一结果,所有结果的长度固定。
JAVA加密算法(3)- 对称加密算法(DES、3DES、AES)
对称加密算法概念:加密密钥和解密密钥相同,大部分算法加密揭秘过程互逆。
- 特点:算法公开、(相比非对称加密)计算量小、加密速度快、效率高。
- 弱点:双方都使用同样的密钥,安全性得不到保证。
发送者使用接收者的公钥加密,接收者使用自己的私钥解密。需要两个密钥进行加密或解密,分为公钥和私钥
- 特点:安全性高,速度慢
常用签名算法
- RSASignature
- DSASignature
- ECDSASignature(需Bouncy Castle)
前端也要学算法
目前为止我参加过几次前端开发方面的面试,确实有不少面试官会问道一些算法。通常会涉及的,是链表、树、字符串、数组相关的知识。前端面试对算法要求不高,似乎已经是业内的一种共识了。虽说算法好的前端面试肯定会加分,但是仅凭常见的面试题,而不去联系需求,很难让人觉得,算法对于前端真的很重要。
输入输出思想
- 相对于前端程序来说,前端用户的操作为输入,然后经过逻辑处理后,把数据输出到后端;
- 相对于后端程序来说,从数据库取数据算做输入,然后经过处理后,输出到前端展示;
- 相对于数据库来说,对于数据的操作指令为输入,操作后产生的输出结果为输出(如删除成功返回值,写入成功后返回值等)
综合以上,本篇讨论了几个话题:
- 递归和查DOM
- Set/Map的实现
- 数组去重的几种方法比较
- 栈和堆
- 节流
- 图像处理
本篇从前端的角度对一些算法做一些分析和总结,只列了一些我认为比较重要,其它的还有很多没有提及。算法和数据结构是一个永恒的话题,它的目的是用最小的时间和最小的空间解决问题。但是有时候不用太拘泥于一定要最优的答案,能够合适地解决问题就是好方法,而且对于不同的应用场景可能要采取不同的策略。反之,如果你的代码里面动不动就是三四重循环,还有嵌套了很多if-else,你可能要考虑下采用合适的数据结构和算法去优化你的代码。
算法应用
从零到一:用深度优先算法检测有向图的环路(应用场景:性格测试)
淘宝API 相关的签名算法 Node.js版本 (阿里大鱼短信)
算法面试
社区技术群
SegmentFault 官方目前开放的微信技术群如下:
- SF.GG 后端攻城狮交流群
- SF.GG 前端攻城狮交流群
- SF.GG 北京技术交流群
- SF.GG 上海技术交流群
- SF.GG 广州技术交流群
- SF.GG 深圳技术交流群
- SF.GG 杭州技术交流群
以上群组仅限程序员加入,需要入群的小伙伴请添加管理员微信好友:mgr_segmentfault,备注『群名称+SF用户ID』,审核成功后会拉你进入相应技术群。
本期完
:)