做者: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$ 個輸出數組。
若是你要進行技術面試,必須爲展現本身對各類算法的瞭解作好準備,並瞭解每種算法的複雜度。熟悉上面提到的算法範例(即分治、暴力、貪婪),諺語云:「實踐出真知」,因此你須要花時間去練習實現不一樣的算法,並計算其複雜度,由於開發人員在編碼時必須意識到這一點。
你能夠採起一些步驟來確保下次面試成功:
熟悉各類算法:不要只記住解決方案。花時間瞭解構成每種算法的模式以及應該採起的方法。
作功課:練習的次數越多,感受就會越溫馨。
下一步…學習,準備和練習:只是憑藉看老的面試題和博客文章來準備面試是不夠的,你須要真正的實踐經驗。