非算法工程師面試必問的算法面試理論

非算法方向的你前端

面了多少次試?git

最後,由於不懂算法,程序員

死在了半路上?github

這些痛,面試

做爲技術創新型公司的小編——個推君算法

怎麼會不懂?編程

爲此,個推君特請了我司經驗豐富的面試官json

爲你奉上一份熱乎的面試寶典。後端

寶典可不是面試題哦設計模式

僅送給想認真鑽研的童鞋

幫你們梳理知識點

讓你們觸類旁通,

offer拿到手軟!

注:此處建議你們使用 C 語言來學習數據結構與算法。

數據結構

首先咱們得從數據結構開始,你們至少得數據結構有個概念,大部分的算法題均須要帶入數據結構的概念來處理。
科班出身的程序員或多或少學習過數據結構,推薦你們重溫下這本書,溫故而知新。

時間複雜與空間複雜度

在說算法以前和你們科普兩個重要的理論知識:算法的時間複雜度與空間複雜度

時間複雜度:

算法的時間複雜度,用來度量算法的運行時間,記做: T(n) = O(f(n))。它表示隨着 輸入大小n 的增大,算法執行須要的時間的增加速度能夠用 f(n) 來描述,而且會忽略常量部分,。

舉個例子

int aFunc(void) {
    printf("Hello, World!\n");      //  須要執行 1 次
    return 0;       // 須要執行 1 次
}

調用此方法,printf("Hello, World!n"); 執行了一次,那麼咱們記作 T(n) = O(1)

int aFunc(int n) {
    for(int i = 0; i<n; i++) {         // 須要執行 (n + 1) 次
        printf("Hello, World!\n");      // 須要執行 n 次
    }
    return 0;       // 須要執行 1 次
}

此處輸出語句被執行了 n 次,那麼咱們記作 T(n) = O(n)

再看一個

int aFunc(int n) {
    for(int i = 0; i<3*n; i++) {    
        for(int j = 0; j<2*n; i++) {       // 須要執行 (n) 次
        printf("Hello, World!\n");      // 須要執行 n 次
    }
    return 0;      
}

此處輸出語句被執行了 (3n)(2*n) 次,f(n)=6n^2,因爲咱們是忽略常量的,因此 T(n)=O(n^2)

空間複雜度:

是對一個算法在運行過程當中臨時佔用存儲空間大小的量度,記作S(n)=O(f(n))。
int i = 1;
int j = 2;
++i;
j++;
int m = i + j

代碼中的 i、j、m 所分配的空間都不隨着處理數據量變化,所以它的空間複雜度 S(n) = O(1)。

int[] m = new int[n]
for(i=1; i<=n; ++i)
{
   j = i;
   j++;
}

這段代碼中,第一行new了一個數組出來,這個數據佔用的大小爲n,這段代碼的2-6行,雖然有循環,但沒有再分配新的空間,所以,這段代碼的空間複雜度主要看第一行便可,即 S(n) = O(n)

字符串

字符串或串(String)是由數字、字母、下劃線組成的一串字符。通常記爲 s=「a1a2···an」(n>=0)。它是編程語言中表示文本的數據類型。在程序設計中,字符串(string)爲符號或數值的一個連續序列,如符號串(一串字符)或二進制數字串(一串二進制數字)。

這個很少說了,敲代碼的都懂,一切皆可字符串。

數組

所謂數組,是有序的元素序列。若將有限個類型相同的變量的集合命名,那麼這個名稱爲數組名。組成數組的各個變量稱爲數組的份量,也稱爲數組的元素,有時也稱爲下標變量。用於區分數組的各個元素的數字編號稱爲下標。

在 C 語言中,數組可分爲一維數組,二維數組,多維數組等。而涉及到怎麼建立數組這邊就細講了,各個語言的的申明方法以及使用方法都不太相同。

二維數組結構圖

舉例

  • int a[10]; 說明整型數組a,有10個元素。若要表示第10個元素,則使用a[9]。第一個則是a[0]。
  • float b[10],c[20]; 說明實型數組b,有10個元素,實型數組c,有20個元素。
  • char ch[20]; 說明字符數組ch,有20個元素。

鏈表(Node)

鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是經過鏈表中的指針連接次序實現的。鏈表由一系列結點(鏈表中每個元素稱爲結點)組成,結點能夠在運行時動態生成。每一個結點包括兩個部分:一個是存儲數據元素的數據域,另外一個是存儲下一個結點地址的指針域。

鏈表是咱們比較經常使用的數據結構,若是在編程的過程當中,須要進行頻繁 增&刪 操做的,優先使用鏈式存儲結構。
鏈表分爲咱們常見的單鏈表,還有雙鏈表以及循環鏈表

單鏈表結構體

typedef struct LNode
{
    int data;            //data中存放結點數據域(默認是int型)
    struct LNode *next; //指向後繼結點的指針
}LNode;

單鏈表結構圖


棧 (Stack)

棧做爲一種數據結構,是一種只能在一端進行插入和刪除操做的特殊線性表。它按照先進後出的原則存儲數據,先進入的數據被壓入棧底,最後的數據在棧頂,須要讀數據的時候從棧頂開始彈出數據(最後一個數據被第一個讀出來)。棧具備記憶做用,對棧的插入與刪除操做中,不須要改變棧底指針。

棧是一種先進後出的的數據結構,有入棧和入棧兩種常見操做。

結構體

typedef struct Stack{   // 棧
    
    PNODE pTop;
    PNODE pBottom;
    
}STACK,*PSTACK;

結構圖

隊列(Queue)

隊列是一種特殊的線性表,特殊之處在於它只容許在表的前端(front)進行刪除操做,而在表的後端(rear)進行插入操做,和棧同樣,隊列是一種操做受限制的線性表。進行插入操做的端稱爲隊尾,進行刪除操做的端稱爲隊頭。隊列中沒有元素時,稱爲空隊列。

隊列是一種先進先出的的數據結構,有入隊和出隊兩種常見操做,通常有順序隊列,雙向隊列,循環隊列。

結構體

typedef struct{
    ELemType data[MaxSize];
    int front, rear;
}SqQueue;

結構圖

樹(Tree)

它是由n(n>=1)個有限結點組成一個具備層次關係的集合。把它叫作「樹」是由於它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。

樹是一個大類,樹下面又分 二叉樹,平衡二叉樹,AVL 樹,字典樹,哈夫曼樹,紅黑樹,b 樹等,考察的最多的是二叉樹與紅黑樹

結構體

下圖是二叉樹的結構體定義

typedef struct TNode{
    TElemType  data;
    struct TNode *lchild,*rchild;
}TNode,*Tree;

二叉樹結構圖

圖(Graph)

圖是由頂點的有窮非空集合和頂點之間邊的集合組成, 一般表示爲: G(V,E), 其中,G表示一個圖,V是圖G中頂點的集合,E是圖G中邊的集合。

一個圖就是一些頂點的集合,這些頂點經過一系列邊結對(鏈接)。頂點用圓圈表示,邊就是這些圓圈之間的連線。頂點之間經過邊鏈接。頂點有時也稱爲節點或者交點,邊有時也稱爲連接。

結構圖

算法和數據操做

粗略的講了下數據結構的理論,終於要進入正餐了。算法題大體分爲如下幾大類,還有一些小類就不舉例了,好比位運算,回溯算法等。

查找

查找也能夠叫作搜索,這是算法分類裏面最最最普通的一個模塊,查找分爲 線性查找,數表查找,哈希查找

掌握程度: 查找 類型的較多問題,每一種數據結構都有本身的查找類型的經典算法,好比 數組對應的最小值/最大值查找、字符串對應的關鍵字查找、鏈表對應的迴環判斷等、樹對應的深度/廣度優先,二叉樹對應的 前/中/後 遍歷,最 小/大 堆查找 ,這些本質是都是和查找算法相關的。

推薦範例: 這個很差推薦,實在是太多了。

排序

說到排序,你們都很是熟悉了,排序分爲內排序和外排序,由於外排序的出現頻率較低,這邊只進行內排序的分析,咱們常見的選擇,冒泡,快排均屬於內排序。

具體的算法不展開了,百度有全家桶

掌握程度:除了基數排序和希爾排序,其餘幾個排序算法均須要能夠默寫算法的程度,接着要進行實戰操做,刷完下面的這些題目,對排序算法會有個清晰的理解。
推薦範例排序範例

遞歸

講到遞歸的時候,咱們在使用的過程當中,特別要對遞歸終止的條件有個清晰的把握,否則很容易陷入死循環當中

掌握程度:連接裏面的就 14 到題目,但願所有刷一遍。值得注意的是,遞歸的題目通常來講會有多種解法。
推薦範例遞歸集合

動態規劃

動態規劃,又名DP算法(取自其Dynamic Programming的縮寫),最初是運籌學的一個分支,是用來求解決策過程最優化的數學方法。
動態規劃經常適用於有重疊子問題和最優子結構性質的問題,動態規劃方法所耗時間每每遠少於樸素解法。
動態規劃背後的基本思想很是簡單。大體上,若要解一個給定問題,咱們須要解其不一樣部分(即子問題),再根據子問題的解以得出原問題的解。動態規劃每每用於優化遞歸問題,例如斐波那契數列,若是運用遞歸的方式來求解會重複計算不少相同的子問題,利用動態規劃的思想能夠減小計算量。好比咱們常見的爬樓梯的問題,對了這個問題通常有多種解法。
掌握程度: 這類問題的類似度很是的高,但願你們能夠達到舉一反三的境界
推薦範例買賣股票的最佳時機爬樓梯

貪心算法

貪心算法(又稱貪婪算法)是指,在對問題求解時,老是作出在當前看來是最好的選擇。也就是說,不從總體最優上加以考慮,他所作出的是在某種意義上的局部最優解。好比咱們常見的爬樓梯問題
掌握程度: 若是不是面試算法工程師的話,建議刷完 10 道簡單的題目便可
推薦範例貪心算法範例

圖這塊知識會涉及到很深很深的東西,若是不是從事這方向研究的,停留在理論層+一些簡單算法便可,圖裏面有不少的經典算法須要掌握。

好比 普利姆算法,克魯斯卡爾算法等,這些都是很是經典的算法,須要知道經典算法的設計邏輯以及優缺點。
掌握程度: 熟悉各種存儲結構,精通經典算法的實現思路
推薦範例圖算法的範例

LeetCode 正確的打開方式

你們有沒有發現上個章節頻繁的出現了 LeetCode 這個字眼,那麼這個網站究竟是什麼呢?在介紹以前還得和你們說下該怎麼刷題嗎。刷題網站有力扣 (LeetCode 中文版),清華 ACM,浙大 ACM,這幾個網站算法學習生態圈都比較穩定,LeetCode 也是其中的一種,我習慣用力扣(力扣的小編看到的話記得給我加個雞腿),這是一個寶藏網站,裏面的內容很是的多,你們感興趣的能夠深刻研究下。

這上面的題目也就 1117 題而已,能夠從不一樣的維度去刷題,好比難易度,問題分類,經過率等。我推薦是根據
數據結構的分類來,好比你今天學了二叉樹,那麼打開 LeetCode,耗時 2 天刷十道簡單題的二叉樹便可。按照這種思路,差很少 1 個月便可完成上述所描述的題目。但願你們時間還來得及


這些都是我我的的一些學習經歷,經過這個網站的可視化界面,能夠較直觀對本身的學習有個回顧。
推薦是用 C 語言,由於 C 語言更接近底層,編譯速度會快那麼零點幾毫秒,別小看幾毫秒的時間哦,由於在 LeetCode 上,算法耗時的最小單位是 1 毫秒。。。差一毫秒但是差異巨大的。


若是你寫的算法僅打敗了 40%的提交記錄,老學長建議你重寫提交下,算法魅力就在於此,毫秒必爭!一個好的算法可讓程序的編譯速度成幾何倍速的增長。 也能夠直接點擊柱狀圖,會有當前算法耗時的最優算法解。

說了一些 LeetCode 的東西,咱們看看實際開發過程當中,安利你們一個 IDEA 的 LeetCode 的插件,名字就叫 leetcode ,使用這個小插件,能夠幫助咱們快速編譯所寫的 demo。

編寫的算法能夠直接在編譯器裏測試 & 提交。

雜談

說個現實的問題,除非是算法工程師,你們在開發的過程當中極少用到算法的,那是否是反向推論算法僅是停留在作題&面試,僅須要應付面試便可了?那是否是隻要瘋狂刷題就能夠了!!!
不過話說回來,不推薦你們這麼玩,推薦你們在理論的基礎上加以實踐,仍是但願你們能夠深刻的學習數據結構與算法,會對計算機的運行有着更深刻的理解,後面是我本身看過的一些書本與優秀公衆號,連接是個人我的刷題庫
https://github.com/LiuLei0571...

書籍推薦

《算法 4 》,《漫畫算法》,《大話設計模式》,《大話數據結構》,《劍指 offer》

大牛推薦

  • 任玉剛老師的《玉剛說》公衆號:會講不少關於算法面試,架構體系,職場分析的文章。
  • 波波老師的《是否是很酷》公衆號:波波老師是我認爲目前把算法與數據結構講的最透徹的講師,你們能夠去 X課網搜一下就可知道

彩蛋

感謝各位看官閱讀到最後,大家的支持是我創做的源泉,最後給你們放一道我在實際開發中遇到的算法問題。

有如下一個 json 字符串,編寫一個算法測試此 json 是否有迴路。action_chains 裏面有若干個動做,入口動做是 actionid=1,接着去執行下一個動做,下一個動做的 actionid 是上一個動做的 do 參數,出口是 actionid=100。
{
    "action_chains": [
        {
            "actionid": "1",
            "do": "2"
        },
        {
            "actionid": "2",
            "do": "3"
        },
        {
            "actionid": "3",
            "do": "4"
        },
        {
            "actionid": "4",
            "do": "5"
        },
        {
            "actionid": "5"  
        }
    ]
}


請關注**個推技術學院**公衆號回覆「答案」便可查閱答案。

![](https://user-gold-cdn.xitu.io/2019/8/28/16cd6db235f68124?w=640&h=427&f=png&s=61758)
相關文章
相關標籤/搜索