数据结构与算法
数据结构与算法问题的难度完全取决于你所申请的公司
- 数组
- 数组由一组相同的数据类型组成。它存储在连续的内存空间内,使用索引可以找到元素的地址。数组包括一维数组和多维数组,一维数组是最简单的数据结构,也是最常用的。
算法 | 平均 | 最坏 |
---|---|---|
空间(Space) | O(n) | O(n) |
查找(Search) | O(n) | O(n) |
插入(Insert) | O(n) | O(n) |
删除(Delete) | O(n) | O(n) |
- 链表
- 链表看起来更像树,而不是数组,它使用一组结点来表示一个序列。每一个结点都包含数据和一个指针。在链表中,结点中的数据可以为任意类型,而指针则是指向下一结点的引用。链表包含一个头结点和一个尾结点。头结点是链表中的第一个结点,尾结点是最后一个结点。链表不是一个循环数据结构,所以尾结点没有指向头结点的指针,指针为空。一些基础方法的时间复杂度如下:
算法 | 平均 | 最坏 |
---|---|---|
空间 (Space) | O(n) | O(n) |
查找 (Search) | O(n) | O(n) |
插入 (Insert) | O(1) | O(1) |
删除 (Delete) | O(1) | O(1) |
双向链表
一个双向链表首先是一个链表,但是在每个结点中有两个指针,前驱指针指向前驱结点,后继指针指向后继结点。双向链表也有一个头结点,头结点的后继指针指向第一个结点。最后一个结点的后继指针指向空,但是如果最后一个结点的后继指针指向第一个结点,这时称这个链表为双向循环链表。双向循环链表能非常方便地从每个结点查找它的前驱结点和后继结点。
算法 | 平均 | 最坏 |
---|---|---|
空间 (Space) | O(n) | O(n) |
查找 (Search) | O(n) | O(n) |
插入 (Insert) | O(1) | O(1) |
删除 (Delete) | O(1) | O(1) |
栈
栈是一个有着「后进先出」特性的基础数据结构,这就意味着最后一个入栈的元素,也是第一个出栈的。栈就像是一堆书,想要得到书堆中的第一本书(最下面一本),必须把其他的书都先拿走。向栈中添加一个元素的操作被称为 Push(入栈),删除一个元素的操作被称为 Pop(出栈),查看且不删除最后一个入栈的元素的操作被称为 Top 。实现栈的常用方法是使用链表(LinkedList),也可以使用不允许空值的 StackArray(使用数组实现),还有允许空值的 Vector
算法 平均 最坏 图形表示 空间 (Space) O(n) O(n) 查找 (Search) O(n) O(n) 入栈 (Push) O(1) O(1) 出栈 (Pop) O(1) O(1) 查看栈顶 (Top) O(1) O(1)
队列
优先队列
动态编程
字符串操作
二叉树
二叉搜索树
排序算法
哈希表与哈希图
广度优先搜索
深度优先搜索
贪心算法
所谓贪心算法(贪婪算法),是在求解一个问题时,作出当前最好的选择,而不考虑大局。也就是说,这种算法的每一种实现,只是在作出一个某种方面上的局部最优解。
我们可以说贪心算法是「短视的」, 「不可恢复」的
此算法没有固定框架,只有每个人贪心策略的选择,而导致的不同姿态的代码实现。
来自wikipedia:
贪心法,又称貪心演算法、貪婪演算法、或稱貪婪法,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。[1]比如在旅行推销员问题中,如果旅行员每次都选择最近的城市,那这就是一种贪心算法。
贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。
贪心算法与动态规划的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。
贪心法可以解决一些最优化问题,如:求图中的最小生成树、求哈夫曼编码……对于其他问题,贪心法一般不能得到我们所要求的答案。一旦一个问题可以通过贪心法来解决,那么贪心法一般是解决这个问题的最好办法。由于贪心法的高效性以及其所求得的答案比较接近最优结果,贪心法也可以用作辅助算法或者直接解决一些要求结果不特别精确的问题。