演算法和程式設計面試題精選 TOP50!(附程式碼+解題思路+答案)
本篇文章的面試資源,主要包含五部分內容:陣列、連結串列、字串、二叉樹和重要演算法(如排序演算法)的程式設計面試題,其中每部分內容,都列出了一些最常被問到的熱門問題。並且在每個題目後,給出了可以參考的解決思路和程式碼。因為題目較多,我們沒有羅列所有的方法和程式碼,只給出了訪問地址。相信大家在掌握了這些內容後,一定可以提升實力、信心大增。
作者 | javinpaul
出品 | AI科技大本營
陣列
陣列,將元素儲存到記憶體的連續位置中,是最基本的資料結構。在任何和程式設計相關的面試中,都會被問到和陣列相關的問題,可以說是非常熱門的考題之一。比如:將陣列反轉、對陣列進行排序、搜尋陣列中的元素等。
陣列資料結構的主要優點是如果知道索引就可以通過 O(l) 進行快速搜尋,但是在陣列中新增和刪除元素的速度會很慢,因為陣列一旦被建立,就無法更改其大小。如果需要建立更長或更短的陣列,得先建立一個新陣列,再把原陣列中的所有元素複製到新建立的陣列中。
解決陣列相關問題的關鍵是要熟悉陣列的資料結構和基本的構造,如迴圈、遞迴等等;下面給出了 10 道熱門面試題幫助大家掌握知識並進行練習。
1.給定一個 1-100 的整數陣列,請找到其中缺少的數字。
解決方法與程式碼:
https://javarevisited.blogspot.com/2014/11/how-to-find-missing-number-on-integer-array-java.html
2.請在給出的整數陣列中找到重複的數字。
解決方法與程式碼:
http://javarevisited.blogspot.com/2014/01/how-to-remove-duplicates-from-array-java-without-collection-API.html
3.如何在未排序的整數陣列中找到最大值與最小值?
解決方法與程式碼:
http://java67.blogspot.com/2014/02/how-to-find-largest-and-smallest-number-array-in-java.html
4.在給定的成對整數陣列中,請找出所有總和等於給定數字的組合。
解決方法與程式碼:
http://javarevisited.blogspot.com/2014/08/how-to-find-all-pairs-in-array-of-integers-whose-sum-equal-given-number-java.html
5.如果陣列中有多個重複項,如何找到重複的數字?
解決方法與程式碼:
http://javarevisited.blogspot.com/2014/03/3-ways-to-find-first-non-repeated-character-String-programming-problem.html
6.用 Java 語言實現,在給出的陣列中,刪除重複項。
解決方法與程式碼:
http://javarevisited.blogspot.com/2014/01/how-to-remove-duplicates-from-array-java-without-collection-API.html
7.用 quicksort 演算法實現對整數陣列的排序。
解決方法和程式碼:
http://javarevisited.blogspot.com/2014/08/quicksort-sorting-algorithm-in-java-in-place-example.html
8.如何刪除現有陣列中的重複項?
解決方法和程式碼:
http://javarevisited.blogspot.com/2014/01/how-to-remove-duplicates-from-array-java-without-collection-API.html
9.用 Java 語言把陣列進行反轉。
解決方法和程式碼:
http://javarevisited.blogspot.com/2013/03/how-to-reverse-array-in-java-int-String-array-example.html
10.如何在不呼叫庫的情況下刪除陣列中的重複項?
解決方法和程式碼:
http://javarevisited.blogspot.sg/2014/01/how-to-remove-duplicates-from-array-java-without-collection-API.html
十個問題太少?更多複雜問題,可訪問:http://javarevisited.blogspot.sg/2015/06/top-20-array-interview-questions-and-answers.html
連結串列
連結串列是另一種常見的資料結構,和陣列相似,連結串列也是線性的資料結構並且以線性方式儲存元素。而與陣列不同的是,連結串列不是將元素儲存在連續的位置中,而是可以儲存在任意位置,彼此之間通過節點相互連線。
連結串列也可以說就是一個節點列表,每個節點中包含儲存的值和下一個節點的地址。也正是因為這種結構,在連結串列裡新增和刪除元素很容易,你只需要更改連結而不用建立新的陣列。但是搜尋會很困難,並且在單鏈表中找到一個元素就需要 O(n)個時間。
連結串列有多種形式,如:單鏈表,允許你在一個方向上進行遍歷;雙鏈表,可以在兩個方向上進行遍歷;迴圈連結串列,最後節點的指標指向第一個節點從而形成一個環形的鏈;因為連結串列是一種遞迴資料結構,所以在解決連結串列問題時,熟練掌握遞迴演算法就顯得更加重要了。
下面是關於連結串列的一些最常見、熱門的面試問題,大家可以著重練習:
1.如何在一次遞迴後找到單鏈表的中間元素?
解決方法和程式碼:
http://javarevisited.blogspot.sg/2012/12/how-to-find-middle-element-of-linked-list-one-pass.html
2.檢查給定的連結串列中是否包含迴圈連結串列,並找出迴圈連結串列的起始節點。
解決方法和程式碼:
http://javarevisited.blogspot.sg/2013/05/find-if-linked-list-contains-loops-cycle-cyclic-circular-check.html
3.如何將列表反轉(倒置)?
解決方法和程式碼:
http://www.java67.com/2016/07/how-to-reverse-singly-linked-list-in-java-example.html
4.如何在沒有遞迴的情況下反轉單鏈表?
解決方法和程式碼:
http://javarevisited.blogspot.sg/2017/03/how-to-reverse-linked-list-in-java-using-iteration-and-recursion.html
5.刪除未經過排序的連結串列中重複的節點。
解決方法和程式碼:
https://www.geeksforgeeks.org/remove-duplicates-from-an-unsorted-linked-list/
6.計算單鏈表的長度。
解決方法和程式碼:
http://javarevisited.blogspot.sg/2016/05/how-do-you-find-length-of-singly-linked.html
7.找出單鏈表中倒數第三個節點。
解決方法和程式碼:
http://javarevisited.blogspot.sg/2016/07/how-to-find-3rd-element-from-end-in-linked-list-java.html
8.如何使用 Stack 查詢兩個連結串列的和?
解決方法和程式碼:
https://www.geeksforgeeks.org/sum-of-two-linked-lists/
這些問題可以幫你提升解決問題的能力,加深對連結串列資料結構的瞭解。
關於陣列和連結串列間的區別,可詳細閱讀:
http://javarevisited.blogspot.sg/2013/07/difference-between-array-and-linked-list-java.html
更多複雜問題,可訪問:
http://javarevisited.blogspot.sg/2017/07/top-10-linked-list-coding-questions-and.html
字串
除了陣列和連結串列資料結構,字串是應聘過程中程式設計面試的另一個熱門問題。在我參加過的程式設計面試中,每一個都涉及了有關字串的問題。
值得慶幸的是,如果你瞭解陣列,你可以很容易解決關於字串的問題,因為字串本身就是一個由字元組成的陣列。
因此,你學過的所有用來解決陣列程式設計問題的知識,也可以用來解決字串的程式設計問題。
以下是一些在程式設計面試中高頻出現的字串問題:
1.如何輸出字串中重複的字元?
解決方法與程式碼:
http://java67.blogspot.sg/2014/03/how-to-find-duplicate-characters-in-String-Java-program.html
2.如何判斷兩個字串是否互為迴文?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2013/03/Anagram-how-to-check-if-two-string-are-anagrams-example-tutorial.html
3.如何找出字串首個非重複的字元?
解決方法與程式碼:
https://javarevisited.blogspot.com/2014/03/3-ways-to-find-first-non-repeated-character-String-programming-problem.html
4.如何用遞迴的方法將字串進行反轉?
解決方法與程式碼:
https://javarevisited.blogspot.com/2012/01/how-to-reverse-string-in-java-using.html
5.如何判斷一個字串是否只包含數字?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2012/10/regular-expression-example-in-java-to-check-String-number.html
6.如何找到字串中重複的字元?
解決方法與程式碼:
http://java67.blogspot.sg/2014/03/how-to-find-duplicate-characters-in-String-Java-program.html
7.如何計算一個字串中母音字母和子音字母的個數?
解決方法與程式碼:
http://java67.blogspot.sg/2013/11/how-to-count-vowels-and-consonants-in-Java-String-word.html
8.如何計算一個給定字元在字串中出現的次數?
解決方法與程式碼:
https://javarevisited.blogspot.com/2012/12/how-to-count-occurrence-of-character-in-String.html
9.如何找出一個字串的所有排列組合?
解決方法與程式碼:
http://javarevisited.blogspot.com/2015/08/how-to-find-all-permutations-of-string-java-example.html
10.在不使用任何方法庫的情況下,如何將一句話中的單詞進行反轉?
解決方法與程式碼:
http://www.java67.com/2015/06/how-to-reverse-words-in-string-java.html
11.如何判斷一個字串是否為另一個字串迴圈移動的結果?
解決方法與程式碼:
http://www.java67.com/2017/07/string-rotation-in-java-write-program.html
12.如何判斷一個字串是否為迴文?
解決方法與程式碼:
http://java67.blogspot.com/2015/06/how-to-check-is-string-is-palindrome-in.html
這些問題有助於提高你對字串資料結構的理解。如果你在沒有外界幫助的情況下,可以解決所有這些字串問題,那麼你的水平已經很棒了。
若想了解更多複雜的問題,建議學習一下《Algorithm Design Manual by Steven Skiena》這本書中的問題,裡面大都是難度很高的演算法問題。
如果你需要更多的練習,可以參考這一組問題,包含20個字串程式設計問題。
問題連結:https://javarevisited.blogspot.com/2015/01/top-20-string-coding-interview-question-programming-interview.html
二叉樹
到目前為止,我們只涉及了線性資料結構,但現實世界的所有資訊都不是以線性的形式展現的,因此出現了樹結構。
樹結構是一種將資料進行分層儲存的資料結構。根據資料儲存方式的不同,存在不同型別的樹,比如二叉樹,其中每個節點至多有兩個子節點。
和二叉查詢樹一樣,它們都是最流行的樹形式的資料結構。因此,你會發現很多問題基於它們的問題,如計算節點數,如何進行遍歷,計算深度,判斷它們是否平衡。
解決二叉樹問題的關鍵是要有紮實的知識理論,如什麼是二叉樹的大小或深度,什麼是葉,以及什麼是節點。還有對當前流行的遍歷演算法的理解,如前序遍歷、後序遍歷和中序遍歷。
下面是一系列常在軟體開發面試中出現的二叉樹熱門問題:
1.如何部署使用二叉查詢樹?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2015/10/how-to-implement-binary-search-tree-in-java-example.html#axzz4wnEtnNB3
2.給定一個二叉樹,如何進行前序遍歷?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2016/07/binary-tree-preorder-traversal-in-java-using-recursion-iteration-example.html#axzz5ArdIFI7y
3.在不使用遞迴的情況下,如何對給定二叉樹進行前序遍歷?
解決方法與程式碼:
http://www.java67.com/2016/07/binary-tree-preorder-traversal-in-java-without-recursion.html
4.給定一個二叉樹,如何進行中序遍歷?
解決方法與程式碼:
http://www.java67.com/2016/08/binary-tree-inorder-traversal-in-java.html
5.在不使用遞迴的情況下,如何使用中序遍歷輸出給定二叉樹的所有節點?
解決方法與程式碼:
http://www.java67.com/2016/08/binary-tree-inorder-traversal-in-java.html
6.如何實現後序遍歷演算法?
解決方法與程式碼:
http://www.java67.com/2016/10/binary-tree-post-order-traversal-in.html
7.在不使用遞迴的情況下,如何對二叉樹進行後序遍歷?
解決方法與程式碼:
http://www.java67.com/2017/05/binary-tree-post-order-traversal-in-java-without-recursion.html
8.如何輸出一個二叉查詢樹的所有葉子?
解決方法與程式碼:
http://www.java67.com/2016/09/how-to-print-all-leaf-nodes-of-binary-tree-in-java.html
9.如何計算一個給定二叉樹的葉子節點數目?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2016/12/how-to-count-number-of-leaf-nodes-in-java-recursive-iterative-algorithm.html
10.給定一個數組,如何對其進行二叉搜尋?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2015/10/how-to-implement-binary-search-tree-in-java-example.html#axzz4wnEtnNB3
如果你覺得自己對二叉樹程式設計的理解還不夠,無法獨自解決這些問題,我列出了我使用過的書籍:http://javarevisited.blogspot.sg/2015/07/5-data-structure-and-algorithm-books-best-must-read.htmlhttp://javarevisited.blogspot.sg/2018/01/top-5-free-data-structure-and-algorithm-courses-java--c-programmers.html
其它演算法程式設計問題
除了資料結構問題,大多數程式設計面試也會問有關演算法、設計、位操作和一般的邏輯問題,在這部分中我會介紹這些問題。
在實際問題中應用這些概念是十分重要的,因為在面試中它們往往都比較難對付。多加練習不僅可以讓你對這些概念更熟悉,也會讓你在面試過程中更有信心。
1.如何實現氣泡排序演算法?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2014/08/bubble-sort-algorithm-in-java-with.html#axzz5ArdIFI7y
2.如何用迭代實現快速排序演算法?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2016/09/iterative-quicksort-example-in-java-without-recursion.html#axzz5ArdIFI7y
3.如何實現插入排序演算法?
解決方法與程式碼:
http://www.java67.com/2014/09/insertion-sort-in-java-with-example.html
4.如何實現歸併排序演算法?
解決方法與程式碼:
http://www.java67.com/2018/03/mergesort-in-java-algorithm-example-and.html
5.如何實現桶排序演算法?
解決方法與程式碼:
https://javarevisited.blogspot.com/2017/01/bucket-sort-in-java-with-example.html
6.如何實現計數排序演算法?
解決方法與程式碼:
http://www.java67.com/2017/06/counting-sort-in-java-example.html
7.如何實現基數排序演算法?
解決方法與程式碼:
http://www.java67.com/2018/03/how-to-implement-radix-sort-in-java.html
8.在不使用第三個變數的情況下,如何交換兩個數字的值?
解決方法與程式碼:
http://www.java67.com/2015/08/how-to-swap-two-integers-without-using.html
9.如何判斷兩個矩形是否有重疊?
解決方法與程式碼:
http://javarevisited.blogspot.sg/2016/10/how-to-check-if-two-rectangle-overlap-in-java-algorithm.html
10.如何設計一個自動販售機?
解決方法與程式碼:
https://javarevisited.blogspot.com/2016/06/design-vending-machine-in-java.html