做者:Educative翻译:疯狂的技术宅前端
https://www.educative.io/blog...ios
未经容许严禁转载c++
算法是技术面试的重要组成部分,尤为是在国内外的大厂中。本文将为你介绍在面试中须要了解的常见算法以及提升它们效率的方法(这是面试中常见的问题),最后会为你提供一些练习题。程序员
你须要审视的基本概念是:面试
一旦掌握了基础知识,就能够开始进入在面试以前应该了解的中间概念;具体来讲,本文将向你展现一些关键的算法范例(以及使它们高效的方法),这些范例对于学习解决面试中的编码问题相当重要。算法
在咱们深刻研究算法范式以前,应该对计算机程序相对于算法的时间复杂性和效率说些什么——一种被称为“渐近分析”的概念。在面试中,可能不会要求你直接计算算法的复杂度,但可能会要求你计算所编写的算法的复杂度或让你改善一个算法的复杂度。segmentfault
复杂度是算法效率的近似度量,而且与你编写的每一个算法都相有关。这是全部程序员都必须意识到的事情。有两种复杂度:时间和空间。时间复杂度和空间复杂度实质上是算法处理某些输入时将分别花费多少时间和多少空间的近似值。一般要解决如下三个问题:数组
Big O 是分析算法的首选方法,由于在大多数状况下,平均状况和最佳案例没法洞察算法的效率。服务器
若是你在面试中被要求找到算法的 Big O 复杂性,这是通常的经验法则:微信
例:找到时间复杂度为 3n³ + 4n + 2的算法的 Big O 复杂度,将其简化为O(n³)。
计算算法的时间复杂度时,你须要采起三个步骤:
这是一个简单的例子,用于测量大小为 n
的 for 循环的时间复杂度。这是一个大小为 n
的循环:
#include <iostream> using namespace std; int main(){ int n = 10; // 0(1) int sum = 0; // 0(1) for (int i=0; i<n; i++) sum+=2; // 0(1) cout << sum; // 0(1) return 0; }
首先,将代码分红多个单独的操做,而后计算执行该代码的次数,以下所示:
在对每一个操做执行了多少次进行计数以后,只需将全部这些计数相加便可得出该程序的时间复杂度。
$$ \begin{align} 时间复杂度 & = 1 + 1 + 1 +(n + 1)+ n + n + 1 \\ & = 3 +(n + 1)+ 2n + 1 \\ & => 3n + 5 \end{align} $$
渐进分析的通常技巧:
用于计算算法时间复杂度的有用公式:
算法范式是“构建有效解决问题的通用方法”;换句话说,它们是解决问题的方法、策略或技术,对于每一个程序员都是必不可少的。花时间学习这些,由于你颇有可能会在面试中用到其中一种或多种算法。
算法范式之因此出色,是由于它们奠基了适合解决各类不一样问题的框架,包括:
渐近分析:计算下面给出的代码段的 Big O 复杂度。
int main(){ int n = 10; int sum = 0; float pie = 3.14; for (int i=1; i<n; i+=3){ cout << pie << endl; for (int j=1; j<n; J+=2){ sum += 1; cout << sum << endl; } } }
排序和搜索算法:实现一个函数,该函数接受两个可变长度的排序数组,并找到两个数组的中位数。
图算法:实现一个函数,该函数返回给定级别的无向图的节点数。
贪心算法:假设存在无限数量的 25 美分,10 美分,5 美分和 1 美分硬币,实现一个函数来计算表明 V 美分的硬币数量。
动态规划算法:一个孩子正在上 n 级楼梯,每次能够走 1 步,2 步或 3 步。实现一个函数,计算孩子上楼梯的可能方式。
分治法:给定 2 个有 k 行和 44 个排序列的二维数组,以及一个大小为 $k \times n$ 的空一维输出数组,用分治法将全部元素从 k 个排序数组复制到 $k \times n$ 个输出数组。
若是你要进行技术面试,必须为展现本身对各类算法的了解作好准备,并了解每种算法的复杂度。熟悉上面提到的算法范例(即分治、暴力、贪婪),谚语云:“实践出真知”,因此你须要花时间去练习实现不一样的算法,并计算其复杂度,由于开发人员在编码时必须意识到这一点。
你能够采起一些步骤来确保下次面试成功:
熟悉各类算法:不要只记住解决方案。花时间了解构成每种算法的模式以及应该采起的方法。
作功课:练习的次数越多,感受就会越温馨。
下一步…学习,准备和练习:只是凭借看老的面试题和博客文章来准备面试是不够的,你须要真正的实践经验。