我的麵試題總結
(2014-07-28 15:16:17)
下一個
我的麵試題總結
發信站: BBS 未名空間站 (Sat Oct 26 19:32:12 2013, 美東)
好多人問,我就發到這裏吧。
麵試題的構成和分類
首先聲明一下,這裏的麵試題主要所指數據結構和算法的題目,題目的分析集中在
Leetcode上麵的題目上。
我認為一道麵試題由以下幾個方麵組成的
Question
Data structure in question
Data structure in solution
Algorithm in solution
Coding
題目:非常關鍵,一個題目通常有一些相應的變形題目,同一個題目可能有不同的要求
。比如時間複雜度,空間複雜度的要求,比如recursive,
iterative的要求。而根據題目的變形與要求,可能會極大的影響到你能夠采取的數據
結構和算法。
問題中的數據機構:問題中有可能帶數據結構,有可能沒有數據結構,有可能是可以自
定義數據結構
解決方案中的數據結構:可以是in-place的,也就是利用已有的數據結構,也可能是創
建新的數據結構。新的數據結構跟已有的數據結構沒有必然的聯係,而很多問題都是一
題多解,可能采取不同的數據結構。
算法:一般來說,當解決方案中的數據結構確定以後,算法也就確定了。同樣,一旦解
決方案的算法確定,相應的數據結構也就確定了。這兩個沒有先後的關係,但解決方案
中的數據結構和算法具有非常緊密的聯係。
代碼:非常關鍵。代碼就是解決方案的數據結構和算法的實現了。目前來看,題目,數
據結構和算法在麵試中出現的類型比較固定,因此代碼的好壞則是拉開麵試者水平的一
個有效手段。這也是為什麽F,G如此看中代碼的質量了。我發現上麵幾點比較容易突擊
,但是寫代碼的功力還是需要實打實的積累的。
總結麵試題目的關鍵就是要把麵試題目進行分類之後分析。由於麵試題目由以上幾個部
分組成並且混雜在一起,因此怎樣合理的分類就變得非常的困難。其實Careercup150的
分類就比較好,它是這樣進行分類的。
數據結構:Arrays and Strings, Linked Lists, Stacks and Queues, Trees and
Graphs
算法:Bit Manipulation, Mathematics and Probability, Recursion and
Dynamic Programming, Sorting and Searching
但是我感覺這樣分類比較適合初級階段學習,並不適合係統地對麵試題目進行分析。我
其實目前也沒有什麽特別好的idea,想跟著感覺先來,可能慢慢就能悟出更多了。
Peking2麵試題總結(2) - Two/Three pointers
簡稱two pointers吧。大概把分類粗略的搞了一遍(http://leetcode.cloudfoundry.com/),
發現利用two pointers解決的題目數量很大。two pointers我指的是一類題,而不一定
是真正的two pointers,
比如可能是three pointers, 也可能不是pointer, 而是index。這類題基本上就是發
生在array,
string, linked
list這三種數據結構上,是一種基本的算法和編程技巧,同樣超高頻率的出現,可以說
是麵試必遇的題。
two pointers常常和其他的算法混雜起來出現。比如binary search本身也可以歸類為
two
pointers的。如果這樣算的話,Leetcode上邊1/4的題目都跟它相關。因此,two
pointers是必須熟練掌握的基本編程技巧。
Two pointers大概分三種類型
1. 兩個pointers從頭往後走:感覺絕大多數的linked
list的題目都涉及到這個操作,當然還有array。這類題目很多時候又可以稱為sliding
window。
Implement strStr()
Longest Substring Without Repeating Characters
Minimum Window Substring
Remove Duplicates from Sorted Array &
II
Remove Duplicates from Sorted List & II
Remove Element
Remove Nth Node From End of List
Reverse Linked Llist II
Rotate List
Substring with Concatenation of All Words
Swap Nodes in Pairs
2.
兩個pointers從兩頭往中間走:一般麵試出現的的都是singly linked list,
因此這類題主要是array題。
3Sum
3Sum Closest
4Sum
Container With Most Water
Sort Colors
Trapping Rain Water
Two Sum
Binary search (will discuss it in a separate section)
3.
兩個pointers控製兩個不同的數組或鏈表:一般出現在跟merge相關的題目上。
Add Binary
Add Two Numbers
Merge Sorted Array
Merge Two Sorted Lists
Multiply Strings
Partition List
Peking2麵試題總結(3) - Permutation and Combination
基本題,但是非常重要。麵試中碰到任何一題一點也不奇怪。PIE,
CC150和Leetcode都不約而同地包含了這類題。把這些題目做熟是必須的。基本上來說
這類題的解法都是DFS,程序的大體框架非常類似,隻是根據題目的要求代碼稍作修改
。當然每道題也有不同的解法,但是你應該根據自己的喜好把這類題目的解決方案統一
化。熟悉了這類題目以後對於DFS(will
be discussed in a separate section)
的理解會非常深刻。基本上一般的DFS的題目應該沒什麽問題了。
無論是排列還是組合,這類題都有一個變形,就是要求不能有重複的輸出。PIE和CC150
都沒有提到相應的解法,大家應該很好的體會一下。如果沒有相應的準備,屬於麵試的
時候比較容易跪的題目。
Permutation
輸入沒有重複:Permutations, CC150 9.5, PIE Chapter7 Permutations of a
String
輸入有重複,輸出不能有重複:Permutations
II
Next Permutation: 經典算法,背吧
Permutation Sequence: 非常有意思的題目
Combination
純粹的subset
輸入沒有重複:Subsets, CC150 9.4, PIE Chapter7 Combinations of a
String
輸入有重複,輸出不能有重複:Subsets
II
需要滿足一定要求的組合
一個元素隻能取一次(輸入沒有重複): Combinations
一個元素可以取多次(輸入沒有重複): Combination Sum, CC150
9.8
一個元素隻能取一次(輸入有重複,輸出不能有重複):
Combination Sum II
Gray Code: 具有subset的序列特點 (考慮CC150 9.4 Solution#2:
Combinatorics)
Peking2麵試題總結(4) - 數據結構和算法
下邊是我認為麵試中常見的數據結構和算法,以Java的類庫作為標準。
數據結構
Array, ArrayList
String, StringBuffer
LinkedList
HashMap, HashSet
Stack and Queue
Tree:
BT: binary tree
BST: binary search tree,
Balanced BST (red-black tree): TreeMap, TreeSet
Trie: prefix tree
Heap: PriorityQueue
Grpah
注意:
Array和Linkedlist是最最基本的數據結構,因為他們可以構造很多其他的數據結構,
比如String
(C語言裏String就是字符數組),HashMap, Stack和Queue
(Java裏Queue就是LinkedList實現了Queue的interface;
Ruby裏stack和queue都是array), 以及Heap。
Heap is a tree logically, but array physically.
HashMap, Stack and
Queue通常不會出現在問題裏的數據結構中,因此一般作為solution的數據結構。但是
麵試中也常會讓你實現這三種數據結構,另外就是CC150的3.2和3.5都是典型的Stack和
Queue的題。Leetcode中並不涵蓋這些內容,這幾種數據結構在Leetcode中都是作為
solution數據結構出現的
(沒有的原因是這些題目不太適合OJ,因此需要單獨練習)。
目前Leetcode還不包含graph的題型
算法
Sort: quick sort, merge sort, count sort, heap sort, bucket sort,
radix sort, external sort, K selection etc.
Merge: 2 array/list merge, k-way merge, interval merge
etc.
Binary search:
Stack:
Recursion and Iteration:
DFS:pre-order, in-order, post-order for trees
BFS: 需要用Queue
DP: Top down and bottom up
Greedy:
Toposort: 需要用Queue
注意:
Leetcode並沒有包含各種sort算法,而通常麵試很少讓你直接去實現sort算法,但是大
部分的相關編程技巧是包含在很多題目當中的,
比如quick sort的two pointers。
Merge跟sort是緊密相關的,單獨拿出來是因為有很多這個類型的題目,需要一起總結
。Merge操作的對象基本都是已經排好序的。
Stack雖說是數據結構,但是一般出現在solution裏,因此代表了一類算法
Toposort麵試作為難題也很有可能遇到,目前Leetcode還沒有包括進去
Peking2麵試題總結(5) - Binary search and divide and conquer
玩競賽對麵試不利的一個地方就是麵試經常遇到的數據結構比如LinkedList, Tree, 和
算法Binary
search,競賽很少涉及到,因此一直心裏都感覺到有些不安。
Binary search非常tricky,雖說道理簡單,但是麵試的時候卻很容易出bug,因此總結
一下是必須的。假設i=0,
j=A.length-1, 我做了一下LeetCode上的所有binary
search的題目,發現了以下幾點值得注意。
終止條件不同 i<=j, i<j
mid的上下取向不同 i+(j-i)/2, j-(j-i)/2
如何合理分半
分半的時候取=mid, mid-1, or mid+1
Search a 2D Matrix: 這是一道普通的binary search。終止條件i<=j,
mid取向i+(j-i)/2, 分半的時候=mid-1 or mid+1。
Search for a Range:這道題需要終止條件i<j,
mid取向兩種都需要用到,分半的時候需要用到=mid。我發現一般=mid的時候,終止條
件往往是i<j,
不然會有死循環。
如何合理分半:下邊這幾道題都很tricky,分半的時候都有各自的特點,很不容易一次
寫對。需要多多練習和體會。
Search in Rotated Sorted Array
Search in Rotated Sorted Array II
Median of Two Sorted Arrays
還有一個有趣的現象就是很多數學相關的題目也是通過binary search來解決的:
Divide Two Integers:這題沒做過麵試也容易跪
Pow(x, n)
Sqrt(x):其實算是一道典型的binary
search題目,不過裏邊包括了幾個tricky的地方,很難一次寫對
總的來說,LeetCode上邊的這些binary
search的題目cover的還比較全麵,而且題目全部是麵試高頻題,需要練習一次寫對。
Peking2麵試題總結(6) - Linked List
首先LeetCode上幾乎所有的Linked list的題目都可以用two pointers來解決,或者會
用到two
pointers這個基本編程技巧。因此two pointers跟linked list是緊密相關的。因為two
pointers以前已經總結過了,就不多講了。
其次,因為LinkedList和Array/ArrayList一樣都具備有List的特性,因此很多題目都
出現在了兩種數據結構上,或者說很多題目都是可以把這兩種數據結構互換的。比如:
Add Two Numbers
Convert Sorted List to Binary Search
Tree
Insert Interval
Merge Intervals
Merge k Sorted
Lists
Merge Two Sorted
Lists
Remove Duplicates from Sorted
List
Remove Duplicates from Sorted List
II
第三,LinkedList的題目大多自然而然使用iteration來解決的,但是我發現有些時候
iteration比較容易出bug,換成recursion實現更容易。麵試的時候萬一iteration卡住
可以換換recursion的思路。
第四,dummy head非常有用,可以使代碼簡潔很多,並且容易寫bug
free的code。這個技巧可以大量使用。
第五,今天做了一遍LinkedList的題目,發現兩個地方容易出bug。一是two pointers
loop完之後常常會有一個收尾的工作,比如Add Two
Numbers需要處理carrier>0的情況。二是在swap了nodes之後,新的tail需要把next置
空,不然就出現死循環了。
麵試題總結(7) - Tree
一直沒有總結Tree,這次想總結一下結果卻發現沒有什麽太多可以總結的。Leetcode上
tree的題目還是比較全麵的。我做了一遍發現基本上跑不出三個套路:
1. Recursive DFS
2. Iterative DFS
3. BFS
有些tree的題目比較tricky一些,但是最終解法還是逃不出這三個套路,所以我覺得麵
試的時候代碼的質量就變得更加的重要了。因為沒有什麽太多總結的,下邊就隨便聊一
下了。
Leetcode上graph的題目涉及的很少,不過從算法和coding來說DFS,BFS完全適用於
tree和graph。因此,把tree的題目練好了,graph的多數題目應該也不會有什麽問題才
對。當然graph涉及的算法比tree還是要多的,比如shortest
path,
toposort等等,但是DFS,BFS還是基本中的基本。因此做Leetcode上的tree的題目也相
當於練習了graph的題目了。
由於Tree的題目比較多,我感覺一些可以skip掉,如果時間不充裕的話。或者做一遍即
可,不需要反複練習。這些題目或者太簡單,或者麵試不太可能碰到。
Balanced Binary Tree
Binary Tree Level Order Traversal II
Maximum Depth of Binary Tree
Minimum Depth of Binary Tree
Same Tree
Symmetric Tree
Unique Binary Search Trees
Unique Binary Search Trees II
Pre-order, In-order, Post-order traversal
需要會recursive和iterative的兩種實現方式。可惜Leetcode上隻包含了In-order,有
些遺憾。
Tree的serialization/deserialization也是常常被考到的題目,這個Leetcode目前還
沒有包含,當然套路還是DFS/BFS。
LinkedList和Binary Tree相互轉換的題目。
Convert Sorted List to Binary Search Tree
Flatten Binary Tree to Linked List
(這題原題在CC150是一道雙向鏈表題,不知道Leetcode上怎麽改單向了。雙向鏈表應該
更複雜一些,大家要注意一下)
In the companies I worked for, we did have data structure and algorithm questions for entry level system analyst or data analyst positions. However, those questions were more problem-solving oriented. For example, how would you find a person from a white page phone book (what data structure and algorithm to use)? A simple question with no right or wrong answers, but a graduate student's answer may be very different from a undergraduate's.