注:本文摘自唐巧博客,方便以后查閱。請諒解
序
大家都開始上班了吧?我春節(jié)在家準(zhǔn)備了 5 篇面試題系列的文章,想著大家過節(jié)估計(jì)也沒興趣閱讀,所以節(jié)后再發(fā)。這些題目大都選自 LeetCode,屬于簡單到中等類型的難度。還在糾結(jié)學(xué)算法有沒有用的同學(xué),請參閱:搞 iOS 的學(xué)算法有意義嗎?
解題代碼都是使用 Swift 完成的,我也盡量在代碼中使用了 Swift 語言的一些特性,大家可以順便學(xué)學(xué) Swift。
Have fun!
問題
給你一棵二叉樹,請按層輸出其的節(jié)點(diǎn)值,即:按從上到下,從左到右的順序。
例如,如果給你如下一棵二叉樹:

輸出結(jié)果應(yīng)該是:

代碼模版
本題的 Swift 代碼模版如下:

解答
本題出自 LeetCode第 102 題,是一個(gè)典型的有關(guān)遍歷的題目。為了按層遍歷,我們需要使用「隊(duì)列」,來將每一層的節(jié)點(diǎn)先保存下來,然后再依次處理。
因?yàn)槲覀儾坏枰磳觼肀闅v,還需要按層來輸出結(jié)果,所以我在代碼中使用了兩個(gè)隊(duì)列,分別名為level和nextLevel,用于保存不同層的節(jié)點(diǎn)。
最終,整個(gè)算法邏輯是:
1、判斷輸入?yún)?shù)是否是為空。
2、將根節(jié)點(diǎn)加入到隊(duì)列l(wèi)evel中。
3、如果level不為空,則:
? ? ? 3.1 將level加入到結(jié)果ans中。
? ? ?3.2 遍歷level的左子節(jié)點(diǎn)和右子節(jié)點(diǎn),將其加入到nextLevel中。
? ? ?3.3 將nextLevel賦值給level,重復(fù)第 3 步的判斷。
4、將ans中的節(jié)點(diǎn)換成節(jié)點(diǎn)的值,返回結(jié)果。
因?yàn)槲覀兪怯?Swift 來實(shí)現(xiàn)代碼,所以我使用了一些 Swift 語言的特性。例如:隊(duì)列中我們保存的是節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu),但是最終輸出的時(shí)候,我們需要輸出的是值,在代碼中,我使用了 Swift 的函數(shù)式的鏈?zhǔn)秸{(diào)用,將嵌套數(shù)組中的元素類型做了一次變換,如下所示:

另外,我們也使用了 Swift 特有的guard關(guān)鍵字,來處理參數(shù)的特殊情況。
完整的參考代碼如下:

微信中排版代碼非常不便,所以上述代碼也可以從我的 Gist 中找到:https://gist.github.com/tangqiaoboy/a7d24ac5ca266d650aaa91615f39ffae
完成這道題的同學(xué),可以試著練習(xí)一下 LeetCode 的第 107 題,看看能不能只改動(dòng)一行代碼,就把 107 題也解決掉。
歡迎大家把自己的代碼也放到 gist 上回復(fù)給我,Objective-C 或 Swift 的都行。
玩得開心