程式設計師程式碼面試指南:IT名企演算法與資料結構題目最優解

CiCi島發表於2018-12-05

網站

更多書籍點選進入>> CiCi島

下載

電子版僅供預覽及學習交流使用,下載後請24小時內刪除,支援正版,喜歡的請購買正版書籍

封頁

封頁

編輯推薦

如何在IT名企的面試中脫穎而出、一舉成名?《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》就是你應該擁有的“神兵利器”。“刷”完本書,你就是“題王”! 對於每一個程式設計師來說,提升演算法和資料結構等方面的能力至關重要。無數碼農和程式設計愛好者“深陷”題海之中,無論你是為了程式碼面試、提升能力而不情願地刷題,還是愛好所致沉迷於此,這都是你值得擁有的案頭書。   這裡有你在別處找不到的優解分析,有高頻出現在IT名氣程式碼面試中的真題,有讓人拍案驚歎巧妙的題目解法,也有讓你工作中的程式設計難題迎刃而解的啟發……

內容簡介

      《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》是一本程式設計師面試寶典!

      《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》對IT名企程式碼面試各類題目的解進行了總結,並提供了相關程式碼實現。針對當前程式設計師面試缺乏專業題目彙總這一痛點,《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》選取將近200道真實出現過的經典程式碼面試題,幫助廣大程式設計師的面試準備做到萬無一失。“刷”完本書後,你就是“題王”!
      《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》採用題目 解答的方式組織內容,並把面試題型別相近或者解法相近的題目儘量放在一起,讀者在學習本書時很容易看出面試題解法之間的聯絡,使知識的學習避免碎片化。《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》將所有的面試題從難到易依次分為“將、校、尉、士”四個檔次,方便讀者有針對性地選擇“刷”題。《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》所收錄的所有面試題都給出瞭解講解和程式碼實現,並且提供了一些普通解法和解法的執行時間對比,讓讀者真切地感受到解的魅力!
      《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》中的題目全面且經典,更重要的是,《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》收錄了大量題目和解分析,這些內容源自筆者多年來“死磕自己”的深入思考。
      碼農們,你們做好準備在IT名企的面試中脫穎而出、一舉成名了嗎?《程式設計師程式碼面試指南:IT名企演算法與資料結構題目解》就是你應該擁有的“神兵利器”。當然,對需要提升演算法和資料結構等方面能力的程式設計師而言,價值也是顯而易見的。

作者簡介

左程雲,畢業於華中科技大學(本科)、芝加哥大學(碩士),先後就職於IBM、百度。自2010年起專注刷題至今。除刷題之外,興趣廣泛。

目 錄

第1章 棧和佇列

 設計一個有getMin功能的棧(士 ★☆☆☆)

 由兩個棧組成的佇列(尉 ★★☆☆)

 如何僅用遞迴函式和棧操作逆序一個棧(尉 ★★☆☆)

 貓狗佇列(士 ★☆☆☆)

 用一個棧實現另一個棧的排序(士 ★☆☆☆)

 用棧來求解漢諾塔問題(校 ★★★☆)

 生成視窗zui大值陣列(尉 ★★☆☆)

 構造陣列的MaxTree(校 ★★★☆)

 求zui大子矩陣的大小(校 ★★★☆)

 
   第2章 連結串列問題
 列印兩個有序連結串列的公共部分(士 ★☆☆☆)
 在單連結串列和雙連結串列中刪除倒數第K個節點(士 ★☆☆☆)
 刪除連結串列的中間節點和a/b處的節點(士 ★☆☆☆)
 反轉單向和雙向連結串列(士 ★☆☆☆)
 反轉部分單向連結串列(士 ★☆☆☆)
 環形單連結串列的約瑟夫問題(原問題:士 ★☆☆☆ 進階:校 ★★★☆)
 判斷一個連結串列是否為迴文結構(普通解法 士 ★☆☆☆)
 (進階解法 尉 ★★☆☆)
 將單向連結串列按某值劃分成左邊小、中間相等、右邊大的形式(尉 ★★☆☆)
 複製含有隨機指標節點的連結串列(尉 ★★☆☆)
 兩個單連結串列生成相加連結串列(士 ★☆☆☆)
 兩個單連結串列相交的一系列問題(將 ★★★★)
 將單連結串列的每K個節點之間逆序(尉 ★★☆☆)
 刪除無序單連結串列中值重複出現的節點(士 ★☆☆☆)
 在單連結串列中刪除指定值的節點(士 ★☆☆☆)
 將搜尋二叉樹轉換成雙向連結串列(尉 ★★☆☆)
 單連結串列的選擇排序(士 ★☆☆☆)
 一種怪異的節點刪除方式(士 ★☆☆☆)
 向有序的環形單連結串列中插入新節點(士 ★☆☆☆)
 合併兩個有序的單連結串列(士 ★☆☆☆)
 按照左右半區的方式重新組合單連結串列(士 ★☆☆☆)
 
   第3章 二叉樹問題
 分別用遞迴和非遞迴方式實現二叉樹先序、中序和後序遍歷(校 ★★★☆)
 列印二叉樹的邊界節點(尉 ★★☆☆)
 如何較為直觀地列印二叉樹(尉 ★★☆☆)
 二叉樹的序列化和反序列化(士 ★☆☆☆)
 遍歷二叉樹的神級方法(將 ★★★★)
 在二叉樹中找到累加和為指定值的zui長路徑長度(尉 ★★☆☆)
 找到二叉樹中的zui大搜尋二叉子樹(尉 ★★☆☆)
 找到二叉樹中符合搜尋二叉樹條件的zui大拓撲結構(校 ★★★☆)
 二叉樹的按層列印與ZigZag列印(尉 ★★☆☆)
 調整搜尋二叉樹中兩個錯誤的節點(原問題:尉 ★★☆☆)
 (進階問題:將 ★★★★)
 判斷t1樹是否包含t2樹全部的拓撲結構(士 ★☆☆☆)
 判斷t1樹中是否有與t2樹拓撲結構完全相同的子樹(校 ★★★☆)
 判斷二叉樹是否為平衡二叉樹(士 ★☆☆☆)
 根據後序陣列重建搜尋二叉樹(士 ★☆☆☆)
 判斷一棵二叉樹是否為搜尋二叉樹和完全二叉樹(士 ★☆☆☆)
 通過有序陣列生成平衡搜尋二叉樹(士 ★☆☆☆)
 在二叉樹中找到一個節點的後繼節點(尉 ★★☆☆)
 在二叉樹中找到兩個節點的zui近公共祖先(原問題難度:士 ★☆☆☆)
 (進階問題難度:尉 ★★☆☆ 再進階問題難度:校 ★★★☆)
 Tarjan演算法與並查集解決二叉樹節點間zui近公共祖先的批量查詢問題
 (校 ★★★☆)
 二叉樹節點間的zui大距離問題(尉 ★★☆☆)
 先序、中序和後序陣列兩兩結合重構二叉樹(先序與中序結合 士 ★☆☆☆)
 (中序與後序結合 士 ★☆☆☆ 先序與後序結合 尉 ★★☆☆)
 通過先序和中序陣列生成後序陣列(士 ★☆☆☆)
 統計和生成所有不同的二叉樹(尉 ★★☆☆)
 統計完全二叉樹的節點數(尉 ★★☆☆) 

   第4章 遞迴和動態規劃
 斐波那契系列問題的遞迴和動態規劃(將 ★★★★)
 矩陣的zui小路徑和(尉 ★★☆☆)
 換錢的zui少貨幣數(尉 ★★☆☆)
 換錢的方法數(尉 ★★☆☆)
 zui長遞增子序列(校 ★★★☆)
 漢諾塔問題(校 ★★★☆)
 zui長公共子序列問題(尉 ★★☆☆)
 zui長公共子串問題(校 ★★★☆)
 zui小編輯代價(校 ★★★☆)
 字串的交錯組成(校 ★★★☆)
 龍與地下城遊戲問題(尉 ★★☆☆)
 數字字串轉換為字母組合的種數(尉 ★★☆☆)
 表示式得到期望結果的組成種數(校 ★★★☆)
 排成一條線的紙牌博弈問題(尉 ★★☆☆)
 跳躍遊戲(士 ★☆☆☆)
 陣列中的zui長連續序列(尉 ★★☆☆)
 N皇后問題(校 ★★★☆)
 
   第5章 字串問題
 判斷兩個字串是否互為變形詞(士 ★☆☆☆)
 字串中數字子串的求和(士 ★☆☆☆)
 去掉字串中連續出現k個0的子串(士 ★☆☆☆)
 判斷兩個字串是否互為旋轉詞(士 ★☆☆☆)
 將整數字符串轉成整數值(尉 ★★☆☆)
 替換字串中連續出現的指定字串(士 ★☆☆☆)
 字串的統計字串(士 ★☆☆☆)
 判斷字元陣列中是否所有的字元都只出現過一次(按要求一實現的方法 士 ★☆☆☆)
 (按要求二實現的方法 尉 ★★☆☆)
 在有序但含有空的陣列中查詢字串(尉 ★★☆☆)
 字串的調整與替換(士 ★☆☆☆)
 翻轉字串(士 ★☆☆☆)
 陣列中兩個字串的*小距離(尉 ★★☆☆)
 新增zui少字元使字串整體都是迴文字串(校 ★★★☆)
 括號字串的有效性和*長有效長度(原問題 士 ★☆☆☆)
 (補充問題 尉 ★★☆☆)
 公式字串求值(校 ★★★☆)
 0左邊必有1的二進位制字串數量(校 ★★★☆)
 拼接所有字串產生字典順序*小的大寫字串(校 ★★★☆)
 找到字串的*長無重複字元子串(尉 ★★☆☆)
 找到被指的新型別字元(士 ★☆☆☆)
 zui小包含子串的長度(校 ★★★☆)
 迴文zui少分割數(尉 ★★★☆)
 字串匹配問題(校 ★★★☆)
 字典樹(字首樹)的實現(尉 ★★☆☆) 

   第6章 大資料和空間限制
 認識布隆過濾器(尉 ★★☆☆)
 只用2GB記憶體在20億個整數中找到出現次數zui多的數(士 ★☆☆☆)
 40億個非負整數中找到沒出現的數(尉 ★★☆☆)
 找到100億個URL中重複的URL以及搜尋詞彙的top K問題(士 ★☆☆☆)
 40億個非負整數中找到出現了兩次的數和所有數的中位數(尉 ★★☆☆)
 一致性雜湊演算法的基本原理(尉 ★★☆☆) 

   第7章 位運算
 不用額外變數交換兩個整數的值(士 ★☆☆☆)
 不用任何比較判斷找出兩個數中較大的數(校 ★★★☆)
 只用位運算不用算術運算實現整數的加減乘除運算(尉 ★★☆☆)
 整數的二進位制表達中有多少個1(尉 ★★☆☆)
 在其他數都出現偶數次的陣列中找到出現奇數次的數(尉 ★★☆☆)
 在其他數都出現k次的陣列中找到只出現一次的數(尉 ★★☆☆)
 
   第8章 陣列和矩陣問題
 轉圈列印矩陣(士 ★☆☆☆)
 將正方形矩陣順時針轉動90°(士 ★☆☆☆)
 "之"字形列印矩陣(士 ★☆☆☆)
 找到無序陣列中zui小的k個數(O(N*logK)的方法 尉 ★★☆☆)
 (O(N)的方法 將 ★★★★)
 需要排序的zui短子陣列長度(士 ★☆☆☆)
 在陣列中找到出現次數大於N/K的數(校 ★★★☆)
 在行列都排好序的矩陣中找數(士 ★☆☆☆)
 zui長的可整合子陣列的長度(尉 ★★☆☆)
 不重複列印排序陣列中相加和為給定值的所有二元組和三元組(尉 ★★☆☆)
 未排序正數陣列中累加和為給定值的zui長子陣列長度(尉 ★★☆☆)
 未排序陣列中累加和為給定值的zui長子陣列系列問題(尉 ★★☆☆)
 未排序陣列中累加和小於或等於給定值的zui長子陣列長度(校 ★★★☆)
 計算陣列的小和(校 ★★★☆)
 自然數陣列的排序(士 ★☆☆☆)
 奇數下標都是奇數或者偶數下標都是偶數(士 ★☆☆☆)
 子陣列的zui大累加和問題(士 ★☆☆☆)
 子矩陣的zui大累加和問題(尉 ★★☆☆)
 在陣列中找到一個區域性zui小的位置(尉 ★★☆☆)
 陣列中子陣列的zui大累乘積(尉 ★★☆☆)
 列印N個陣列整體zui大的Top K(尉 ★★☆☆)
 邊界都是1的zui大正方形大小(尉 ★★☆☆)
 不包含本位置值的累乘陣列(士 ★☆☆☆)
 陣列的partition調整(士 ★☆☆☆)
 求zui短通路值(尉 ★★☆☆)
 陣列中未出現的zui小正整數(尉 ★★☆☆)
 陣列排序之後相鄰數的zui大差值(尉 ★★☆☆)
 
   第9章 其他題目
 從5隨機到7隨機及其擴充套件(原問題 尉 ★★☆☆ 補充問題 尉 ★★☆☆)
 (進階問題 校 ★★★☆)
 一行程式碼求兩個數的zui大公約數(士 ★★☆☆)
 有關階乘的兩個問題(原問題 尉 ★★☆☆ 進階問題 校 ★★★☆)
 判斷一個點是否在矩形內部(尉 ★★☆☆)
 判斷一個點是否在三角形內部(尉 ★★☆☆)
 摺紙問題(尉 ★★☆☆)
 蓄水池演算法(尉 ★★☆☆)
 設計有setAll功能的雜湊表(士 ★☆☆☆)
 zui大的leftMax與rightMax之差的jue對值(校 ★★★☆)

前 言

推薦序1

  2015年春節,因為公司業務的快速發展,我們開始尋覓優秀的筆試面試演算法講師。幾經週轉,找到了當時在辦線下演算法分享的程雲,認認真真地聽他講了一堂課,當時就認定他就是我們要找的人。

  我聽過很多國內ACM選手的演算法分享,但是每一次聽完以後總覺得我和那些人永遠隔著一個斷裂帶,演算法對我來說遙不可及,而程雲講解演算法的時候總能從小的切口講起,由淺入深,環環相扣,不知不覺引你走向演算法的核心精髓,那種醍醐灌頂的感覺激發大家學習演算法的熱情,一直推著我們前進。

  這幾年IT技術蓬勃發展,日新月異,對技術人才的需求日益增長,程式設計師招聘市場也如火如荼。在有限的三五輪面試中,國外流行讓面試者程式設計解決某些資料結構和演算法的題目,通過觀察面試者編碼的熟練度、思考的速度和深度來衡量面試者的能力和潛力。國內以百度、阿里、騰訊為首的網際網路企業也都逐步開始採用演算法面試來篩選人才。

  程雲出於對演算法的熱愛,長期泡在careercup、leetcode等筆試面試網站上,編碼解決各種筆試面試程式設計題,對各種筆試面試程式設計題的解題技巧了如指掌。

  演算法面試普及後,傳統的資料結構和演算法課本講得太過基礎,又遠離求職,國內也逐漸出現迎合求職需求的筆試面試工具書,這些書籍有些過於應試,純粹以通過面試為導向,程雲的書和那些書相比,題目更前沿,講解更注重思考思路和程式碼的實踐技巧,對每個題目都深挖zui優解,同時根據自己線上下講課學員們的反饋,對每個程式設計考題的解題反覆修改,讓思路更清晰。

  這本書不僅可以作為面試程式碼指南,還可以作為學生課後的輔助練習,刷題5年,悉數總結都沉澱在這本書裡,相信讀者跟著他的引導從頭到尾逐一攻克一定會有所收穫。

  葉向宇

  牛客網CEO

  推薦序2

  初次遇見程雲是在2014年8月,那時我在上一家公司工作剛好滿4年,也是在那時我開始想換個環境,尋找新機會,就試著投了一家公司,結果初次面試遇到演算法題就被淘汰了。後來又面試過其他一些國內網際網路公司,也總是卡在演算法上。其實,之前我曾經自己在家抱著《演算法導論》“啃”了幾章,花了1個月的業餘時間看了前5章,後面就沒再繼續堅持下去。看過的人都知道,雖然很有用,但實在很難“啃”。

  單調地看書很枯燥,於是想到去網上找志同道合的人一起研究,就開始逛演算法論壇。很巧的是,在某個論壇的演算法板塊看到一個帖子,說是在週末有演算法交流班,當時我立即報名,週日的名額已滿,我是很幸運地“替補”上去的。

  還記得初次交流是在程雲租的房子裡,小小的客廳裡放了一張沙發、兩排椅子和一張桌子,桌上放著膝上型電腦和一臺大電視,前面還掛著白板。di一次演算法交流就在這樣的環境裡開始了。

  程雲講起題來猶如行雲流水,我們聽得更是酣暢淋漓,初次聽完就愛上了……當然,我說的是他的講述。

  相信大家都有過這樣的經歷,面對一道演算法題,苦思冥想了半天,還是不知道怎麼解,感覺很沮喪。如果這時突然有人把解題思路和方法以及程式碼都告訴你了,是不是感覺豁然開朗,心情舒暢了?這樣的情景一天出現一次就可以讓人感覺很開心,而如果一天連續出現二十次,那將會是什麼感覺?一個字:爽!

  程雲把每一道題都講解得清晰透徹,有的題目難以理解、思路詭異,他就會不厭其煩地反覆講解,用形象的方式展現複雜的邏輯,直到大家都聽懂為止。給人的感覺可以說是高潮迭起,一波又一波。

  後來第二次交流,我帶來朋友一起參加。之後的交流,我和朋友都毫不猶豫地報名參加。交流的內容涉及經典演算法的高難題目,也有一些小巧玲瓏的技巧題。難題難得讓人歎服,巧題巧得讓人玩味。

  對想去國外大公司就職的程式設計師來說,演算法題這一關是必不可少的。程雲講述的題目是他5年刷題的經驗積累而成,其實只要掌握題目的解題思路和思想,就足以應付國內網際網路公司程式設計師職位的演算法面試題。不過,要想去外國的大公司,比如Google、Facebook之類的,還是要研究得透徹一些才行。

  另外,除應付面試之外,還有很重要的一點,甚至是更重要的一點,就是本書可以幫我們開啟思路,因為很多演算法題的解法是需要逆向思維的,需要跳出原有的固定思維模式,當思維模式被開啟之後,你會發現原有的事物現在看起來會有不同的看法,因為角度變了。不過這隻能自己體會。

  後來才知道,程雲辦演算法交流是為了寫書做準備。用他的話說:“會做題不算什麼,比我刷題多的人我也能找出一把,但能給人講明白就不容易了。”於是我後來又變成了程雲在寫這本書期間的試讀者。

  在此書還未上市之前,就能聽到作者面對面地逐一講解每一道題,真是非常難得且寶貴的經歷。

  如果你和我一樣,對資料結構有個大概的瞭解,很想快速掌握演算法題的解法技巧,那麼這本書一定適合你!

  祝每一位勤奮努力的程式設計師,都能拿到自己滿意的職位!

  周寶鑫

  一個程式設計師

  自序

  我能出書挺意外的。

  在6年前的某一天,雖然我早就知道想進入那些大公司要靠刷程式碼面試題來練習編寫程式碼的能力。可是這一天卻不止如此,我突然有了心情去看程式碼面試題長什麼樣子,於是收集了程式碼面試的題目,越深入,我越有一種恐慌的感覺,因為感覺自己什麼都不太在行,一個歸併排序(Merge sort)寫出完整的程式碼都感覺挺費勁的,面對這個馮·諾伊曼發明的排序演算法,我真有底氣說自己是計算機專業的學生嗎?這種打擊並沒有持續太久,因為愛耍小聰明的人總會特別自信。我決定開始認真面對刷題這件事,但那時我根本不知道我即將面對什麼,更不要談有寫書的念頭了。

  我把課餘時間利用起來,心想:不就是刷題嘛,別人能寫出來,我們也能寫出來。起初的心態是我不服,我就想告訴自己能行。過程虐心是肯定的,經常半夜因為看到一個複雜度特別低的演算法自己真的不能理解而沮喪地睡不著覺。當時覺得找不到什麼資料能徹底讓我明白,書上講的太粗,網上的太散,程式碼寫得看不懂。起初我刷題的時候無數次地想放棄,因為覺得這些都是什麼玩意兒!我為什麼放著好好的日子不過,去找這種罪受?可是我又不甘心,雖然我不懂很多解法,但是它們真的很有意思。

  我將能買到的所有相關書籍上的所有題目全都研究了一遍,不管是中文的還是英文的,我都硬著頭皮“啃”。寫完的每道題後,我都和書上的方法進行反覆比對,“啃”完了五六本書之後,距離我剛開始刷題已經過去16個月了。寫書?別逗了,才剛看完。

  “年輕人總會找藉口說這個東西不是我感興趣的,所以我做不好是應該的。但他們沒有注意的是,你面對的事情中感興趣的事情總是少數,這就使得大多數時候你做事情的態度總是很懈怠、很消極,這使你變成了一個懈怠的人。當你真正面對自己感興趣的東西時,你發現你已經攥不緊拳頭了。”時常想起本科時的畢業設計指導老師——高鵬義老師說的這句話。說得對,對一個東西,如果你沒有透徹研究過,不要輕易說它不精彩。這不是博愛,而是對自己認真。

  刷題程式碼達到4萬行的時候,我基本上成了國內外所有熱門刷題網站的日常使用者,此時我確認了一件事情,今天的程式碼面試指導真的處在一個很初級的階段,這種不健全是全方面的。

  例如:

  經常看到一篇文章前後的語境是割裂的,作者經常根據之前的一個優良解法提出更好的優化方式,但整篇文章都不提之前的解法是什麼。這就導致初學者根本沒有看懂的基礎;

  幾乎所有的書籍都忽略例子帶來的引導作用,甚至還有不少書籍在闡述一個解法的時候只寫虛擬碼,這就使得讀者在看懂意思和自己真正能寫出程式碼之間其實還有很多的路要走;

  程式碼面試題目的特點是“多”、“雜”、“難”,從著手開始學習到*終達到自己想要的效果之間,自己對自己的評估根本無從談起。“慢慢練吧,學海無涯”成為主要的心態,這就難免會產生懷疑的情緒;

  看見一道新的面試題時還是會無從下手,因為之前的學習無法做到舉一反三,對自己做過的題目缺乏總結和歸納。

  難道刷題真的只適合聰明人玩?我不這麼看,既然大多數內容處在有待商榷的地步,那我就去學習原論文吧。

  當時一個人在國外,記得在初冬的一個下午,刷題已經兩年之久,快吃晚飯的時候我突然想起自己忘了吃午飯,就衝出家門去覓食。站在7-11門前的廣場上,我拿著1.5美元的熱狗和75美分的咖啡,微溫的陽光撒在眼睛裡,遠遠地望著即將消失的一天。我停下來,把咖啡放在斑駁的石頭臺子上,咬下熱狗的時候,眼淚就流了下來,越流越多。真苦啊,要爭氣,要把題目做完,要把論文讀完。哭得跟個鬼似的我除了想家,哪裡敢想自己會出書呢?

  當我意識到在網上很難搜到新鮮的題目時,我已經換了兩家公司,反覆實現了600多道題目,寫了差不多10萬行刷題程式碼。原來只是想找份工作,而刷題的初心早就忘了,變成了興趣並堅持了這麼久,我自己也感到意外。更奇怪的是,我已經完全樂在其中,同時交流慾望越來越強,時常和同事們展開這方面的討論。發現了好多書上的解法不是**,發現好多題目其實和同事們討論的做法更好,發現高手特別多,但好像都懶得動筆。

  有一天,我看到自己寫的題目,想到自己那些抓心撓肝的日子,突然覺得要不出書吧?要不專職講題吧?我已經離不開這份感覺了,如果這不是真愛,那什麼才是呢?

  這不是一個勵志的故事,一個愛刷題的人決定把很多解講出來,就這麼簡單。

  左程雲

  2015年7月20日

相關文章