摘要:
动态规划(Dynamic Programming,DP)是指在给定的约束条件下求最优值的算法,在解决问题的过程,需要经历多个决策阶段,每个决策阶段都对应着一组状态。 适用于动态规划解决的问题包含三个特征: (1)最优子结构:通过子问题的最优解,可推导出问题的最优解,即后面阶段的状态可以通过前面阶段的 阅读全文
摘要:
分治算法(Divide-and-Conquer Algorithm),就是分而治之,把一个复杂问题分成两个或更多个相同或相似的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。 分治算法比较适合用递归来实现,而每一层递归都会涉及三个操作: (1)分解:将原问题分解为若干个规模较 阅读全文
摘要:
贪心算法(Greedy Algorithm)会在每一步选择中都采取当前状态下最好或最优(即最有利)的选择,不能回退,从而希望结果是最好或最优的算法。它是动态规划的一种特例,需要满足更多的限制条件。 贪心算法在有最优子结构的问题中尤为有效(例如求图的最小生成树、哈夫曼编码等),最优子结构是指局部最优解 阅读全文
摘要:
回溯算法(backtracking)是一个类似枚举的搜索尝试过程,在寻找问题解的过程中,当发现不满足求解条件时,就退回一步,尝试其它路径,该算法的时间复杂度都不会低于 O(N!),复杂的例题包括正则表达式匹配、解数独等。 在《回溯算法详解》一文中提到,解决一个回溯问题,实际上就是一个决策树的遍历过程 阅读全文
摘要:
二分查找(Binary Search)是对一种针对有序数据集合的查找算法,依赖数组,适合静态数据。通过 n/2^k=1(k 是比较次数),可以求得 k=log2^n,因此时间复杂度为高效地 O(logn)。 其思路很简单,就是每次与区间的中间数据做比较,缩小查找范围,但是期间涉及到的细节很容易踩坑, 阅读全文
摘要:
树是一种非线性表数据结构,树的基本概念如下所列。 (1)结点高度:结点到叶子结点的最长路径(即边数)。例题:112. 路径总和。 (2)结点深度:根结点到这个结点所经历的边的个数。例题:104. 二叉树的最大深度。 (3)结点层数:结点深度加 1。 (4)树的高度:根结点的高度。例题:面试题 04. 阅读全文
摘要:
一、栈 栈(stack)是一种操作受限的线性表数据结构,基于后进先出(LIFO)策略的集合类型,例如函数中的临时变量符合后进先出的特性,因此用栈保存最合适。 在入栈和出栈过程中所需的空间复杂度是 O(1),时间复杂度也是 O(1)。空间复杂度是指运行算法还需要的额外存储空间。 注意,内存中的堆栈和数 阅读全文
摘要:
链表(Linked List)是不同于数组的另一种数据结构,它的存储单元(即结点或元素)除了包含任意类型的数据之外,还需要包含指向另一个结点的引用,后文会用术语链接表示对结点的引用。 下面会列出链表与数组的具体不同: (1)数组需要一块连续的内存空间来存储;而链表则恰恰相反,通过指针将零散的内存串联 阅读全文
摘要:
《浏览器工作原理与实践》是极客时间上的一个浏览器学习系列,在学习之后特在此做记录和总结。 一、事件循环 消息队列是一种数据结构,可以存放要执行的任务。它符合队列“先进先出”的特点,也就是说要添加任务的话,添加到队列的尾部;要取出任务的话,从队列头部去取。 从上图可以看出,改造可以分为下面三个步骤: 阅读全文
摘要:
《浏览器工作原理与实践》是极客时间上的一个浏览器学习系列,在学习之后特在此做记录和总结。 一、执行流程 实际上变量和函数声明在代码里的位置是不会改变的,而且是在编译阶段被 JavaScript 引擎放入内存中。 一段 JavaScript 代码在执行之前需要被 JavaScript 引擎编译,编译完 阅读全文