面試算法實踐與國外大廠習題指南 翻譯自 Kevin Naughton Jr. 維護的倉庫 interviews,包含了在線練習、算法概述與大廠習題實戰等內容。筆者發現正好和以前翻譯的 Java 語法清單 以及 Java 進階面試問題列表 構成面試準備的一些資料合集,從屬於筆者的 Java 入門與實踐系列。java
LeetCodenode
Virtual Judgeandroid
CareerCupgit
HackerRankgithub
Gainlo算法
鏈表便是由節點(Node)組成的線性集合,每一個節點能夠利用指針指向其餘節點。它是一種包含了多個節點的,可以用於表示序列的數據結構。express
Singly-linked list: 鏈表中的節點僅指向下一個節點。編程
Doubly-linked list: 鏈表中的節點不只指向下一個節點,還指向前一個節點。數組
時間複雜度:
索引: O(n)
搜索: O(n)
插入: O(1)
移除: O(1)
棧是元素的集合,其包含了兩個基本操做:push 操做能夠用於將元素壓入棧,pop 操做能夠將棧頂元素移除。
遵循後入先出(LIFO)原則。
時間複雜度:
索引: O(n)
搜索: O(n)
插入: O(1)
移除: O(1)
隊列是元素的集合,其包含了兩個基本操做:enqueue 操做能夠用於將元素插入到隊列中,而 dequeeu 操做則是將元素從隊列中移除。
遵循先入先出原則 (FIFO)。
時間複雜度:
索引: O(n)
搜索: O(n)
插入: O(1)
移除: O(1)
樹便是無向非循環圖。
二叉樹便是每一個節點最多包含左子節點與右子節點這兩個節點的樹形數據結構。
滿二叉樹: 樹中的每一個節點僅包含 0 或 2 個節點。
完美二叉樹: 二叉樹中的每一個葉節點都擁有兩個子節點,而且具備相同的高度。
徹底二叉樹: 除最後一層外,每一層上的結點數均達到最大值;在最後一層上只缺乏右邊的若干結點。
二叉搜索樹(BST)是一種特殊的二叉樹,其任何節點中的值都會大於或者等於其左子樹中存儲的值而且小於或者等於其右子樹中存儲的值。
時間複雜度:
索引: O(log(n))
搜索: O(log(n))
插入: O(log(n))
刪除: O(log(n))
字典樹,又稱基數樹或者前綴樹,可以用於存儲鍵爲字符串的動態集合或者關聯數組的搜索樹。樹中的節點並無直接存儲關聯鍵值,而是該節點在樹中的掛載位置決定了其關聯鍵值。某個節點的全部子節點都擁有相同的前綴,整棵樹的根節點則是空字符串。
樹狀數組又稱 Binary Indexed Tree,其表現形式爲樹,不過本質上是以數組實現。數組中的下標表明着樹中的頂點,每一個頂點的父節點或者子節點的下標可以經過位運算得到。數組中的每一個元素包含了預計算的區間值之和,在整棵樹更新的過程當中一樣會更新這些預計算的值。
時間複雜度:
區間求值: O(log(n))
更新: O(log(n))
線段樹是用於存放間隔或者線段的樹形數據結構,它容許快速的查找某一個節點在若干條線段中出現的次數.
時間複雜度:
區間查詢: O(log(n))
更新: O(log(n))
堆是一種特殊的基於樹的知足某些特性的數據結構,整個堆中的全部父子節點的鍵值都會知足相同的排序條件。堆更準確地能夠分爲最大堆與最小堆,在最大堆中,父節點的鍵值永遠大於或者等於子節點的值,而且整個堆中的最大值存儲於根節點;而最小堆中,父節點的鍵值永遠小於或者等於其子節點的鍵值,而且整個堆中的最小值存儲於根節點。
時間複雜度:
訪問: O(log(n))
搜索: O(log(n))
插入: O(log(n))
移除: O(log(n))
移除最大值 / 最小值: O(1)
哈希可以將任意長度的數據映射到固定長度的數據。哈希函數返回的便是哈希值,若是兩個不一樣的鍵獲得相同的哈希值,即將這種現象稱爲碰撞。
Hash Map: Hash Map 是一種可以創建起鍵與值之間關係的數據結構,Hash Map 可以使用哈希函數將鍵轉化爲桶或者槽中的下標,從而優化對於目標值的搜索速度。
碰撞解決
鏈地址法(Separate Chaining): 鏈地址法中,每一個桶是相互獨立的,包含了一系列索引的列表。搜索操做的時間複雜度便是搜索桶的時間(固定時間)與遍歷列表的時間之和。
開地址法(Open Addressing): 在開地址法中,當插入新值時,會判斷該值對應的哈希桶是否存在,若是存在則根據某種算法依次選擇下一個可能的位置,直到找到一個還沒有被佔用的地址。所謂開地址法也是指某個元素的位置並不永遠由其哈希值決定。
圖是一種數據元素間爲多對多關係的數據結構,加上一組基本操做構成的抽象數據類型。
無向圖(Undirected Graph): 無向圖具備對稱的鄰接矩陣,所以若是存在某條從節點 u 到節點 v 的邊,反之從 v 到 u 的邊也存在。
有向圖(Directed Graph): 有向圖的鄰接矩陣是非對稱的,即若是存在從 u 到 v 的邊並不意味着必定存在從 v 到 u 的邊。
graph in which the adjacency relation is not symmetric. So if there exists an edge from node u to node v (u -> v), this does not imply that there exists an edge from node v to node u (v -> u)
穩定: 否
時間複雜度:
最優時間: O(nlog(n))
最壞時間: O(n^2)
平均時間: O(nlog(n))
合併排序是典型的分治算法,它不斷地將某個數組分爲兩個部分,分別對左子數組與右子數組進行排序,而後將兩個數組合併爲新的有序數組。
穩定: 是
時間複雜度:
最優時間: O(nlog(n))
最壞時間: O(nlog(n))`
平均時間: O(nlog(n))
桶排序將數組分到有限數量的桶子裏。每一個桶子再個別排序(有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序進行排序)。
時間複雜度:
最優時間: Ω(n + k)
最壞時間: O(n^2)
平均時間:Θ(n + k)
基數排序相似於桶排序,將數組分割到有限數目的桶中;不過其在分割以後並無讓每一個桶單獨地進行排序,而是直接進行了合併操做。
時間複雜度:
最優時間: Ω(nk)
最壞時間: O(nk)
平均時間: Θ(nk)
深度優先算法是一種優先遍歷子節點而不是回溯的算法。
時間複雜度: O(|V| + |E|)
廣度優先搜索是優先遍歷鄰居節點而不是子節點的圖遍歷算法。
時間複雜度: O(|V| + |E|)
拓撲排序是對於有向圖節點的線性排序,若是存在某條從 u 到 v 的邊,則認爲 u 的下標先於 v。
時間複雜度: O(|V| + |E|)
Dijkstra 算法 用於計算有向圖中單源最短路徑問題。
時間複雜度: O(|V|^2)
Bellman-Ford 算法 是在帶權圖中計算從單一源點出發到其餘節點的最短路徑的算法。
儘管算法複雜度大於 Dijkstra 算法,可是它適用於包含了負值邊的圖。
時間複雜度:
最優時間: O(|E|)
最壞時間: O(|V||E|)
Floyd-Warshall 算法 可以用於在無環帶權圖中尋找任意節點的最短路徑。
時間複雜度:
最優時間: O(|V|^3)
最壞時間: O(|V|^3)
平均時間: O(|V|^3)
Prim's 算法是用於在帶權無向圖中計算最小生成樹的貪婪算法。換言之,Prim 算法可以在圖中抽取出鏈接全部節點的邊的最小代價子集。
時間複雜度: O(|V|^2)
Kruskal 算法 一樣是計算圖的最小生成樹的算法,與 Prim 的區別在於並不須要圖是連通的。
時間複雜度: O(|E|log|V|)
位運算便是在位級別進行操做的技術,合適的位運算可以幫助咱們獲得更快地運算速度與更小的內存使用。
測試第 k 位: s & (1 << k)
設置第 k 位: s |= (1 << k)
第 k 位置零: s &= ~(1 << k)
切換第 k 位值: s ^= ~(1 << k)
乘以 2: s << n
除以 2: s >> n
交集: s & t
並集: s | t
減法: s & ~t
交換 x = x ^ y ^ (y = x)
Extract lowest set bit: s & (-s)
Extract lowest unset bit: ~s & (s + 1)
大 O 表示 用於表示某個算法的上限,每每用於描述最壞的狀況。
小 O 表示 用於描述某個算法的漸進上界,不過兩者要更爲緊密。
大 Ω 表示 用於描述某個算法的漸進下界。
Little Omega Notation 用於描述某個特定算法的下界,不過不必定很靠近。
Theta Notation 用於描述某個肯定算法的確界。
Data Structures
Algorithms
Competitive Programming 3 - Steven Halim & Felix Halim
Cracking The Coding Interview - Gayle Laakmann McDowell
Cracking The PM Interview - Gayle Laakmann McDowell & Jackie Bavaro
. ├── Array │ ├── bestTimeToBuyAndSellStock.java │ ├── findTheCelebrity.java │ ├── gameOfLife.java │ ├── increasingTripletSubsequence.java │ ├── insertInterval.java │ ├── longestConsecutiveSequence.java │ ├── maximumProductSubarray.java │ ├── maximumSubarray.java │ ├── mergeIntervals.java │ ├── missingRanges.java │ ├── productOfArrayExceptSelf.java │ ├── rotateImage.java │ ├── searchInRotatedSortedArray.java │ ├── spiralMatrixII.java │ ├── subsetsII.java │ ├── subsets.java │ ├── summaryRanges.java │ ├── wiggleSort.java │ └── wordSearch.java ├── Backtracking │ ├── androidUnlockPatterns.java │ ├── generalizedAbbreviation.java │ └── letterCombinationsOfAPhoneNumber.java ├── BinarySearch │ ├── closestBinarySearchTreeValue.java │ ├── firstBadVersion.java │ ├── guessNumberHigherOrLower.java │ ├── pow(x,n).java │ └── sqrt(x).java ├── BitManipulation │ ├── binaryWatch.java │ ├── countingBits.java │ ├── hammingDistance.java │ ├── maximumProductOfWordLengths.java │ ├── numberOf1Bits.java │ ├── sumOfTwoIntegers.java │ └── utf-8Validation.java ├── BreadthFirstSearch │ ├── binaryTreeLevelOrderTraversal.java │ ├── cloneGraph.java │ ├── pacificAtlanticWaterFlow.java │ ├── removeInvalidParentheses.java │ ├── shortestDistanceFromAllBuildings.java │ ├── symmetricTree.java │ └── wallsAndGates.java ├── DepthFirstSearch │ ├── balancedBinaryTree.java │ ├── battleshipsInABoard.java │ ├── convertSortedArrayToBinarySearchTree.java │ ├── maximumDepthOfABinaryTree.java │ ├── numberOfIslands.java │ ├── populatingNextRightPointersInEachNode.java │ └── sameTree.java ├── Design │ └── zigzagIterator.java ├── DivideAndConquer │ ├── expressionAddOperators.java │ └── kthLargestElementInAnArray.java ├── DynamicProgramming │ ├── bombEnemy.java │ ├── climbingStairs.java │ ├── combinationSumIV.java │ ├── countingBits.java │ ├── editDistance.java │ ├── houseRobber.java │ ├── paintFence.java │ ├── paintHouseII.java │ ├── regularExpressionMatching.java │ ├── sentenceScreenFitting.java │ ├── uniqueBinarySearchTrees.java │ └── wordBreak.java ├── HashTable │ ├── binaryTreeVerticalOrderTraversal.java │ ├── findTheDifference.java │ ├── groupAnagrams.java │ ├── groupShiftedStrings.java │ ├── islandPerimeter.java │ ├── loggerRateLimiter.java │ ├── maximumSizeSubarraySumEqualsK.java │ ├── minimumWindowSubstring.java │ ├── sparseMatrixMultiplication.java │ ├── strobogrammaticNumber.java │ ├── twoSum.java │ └── uniqueWordAbbreviation.java ├── LinkedList │ ├── addTwoNumbers.java │ ├── deleteNodeInALinkedList.java │ ├── mergeKSortedLists.java │ ├── palindromeLinkedList.java │ ├── plusOneLinkedList.java │ ├── README.md │ └── reverseLinkedList.java ├── Queue │ └── movingAverageFromDataStream.java ├── README.md ├── Sort │ ├── meetingRoomsII.java │ └── meetingRooms.java ├── Stack │ ├── binarySearchTreeIterator.java │ ├── decodeString.java │ ├── flattenNestedListIterator.java │ └── trappingRainWater.java ├── String │ ├── addBinary.java │ ├── countAndSay.java │ ├── decodeWays.java │ ├── editDistance.java │ ├── integerToEnglishWords.java │ ├── longestPalindrome.java │ ├── longestSubstringWithAtMostKDistinctCharacters.java │ ├── minimumWindowSubstring.java │ ├── multiplyString.java │ ├── oneEditDistance.java │ ├── palindromePermutation.java │ ├── README.md │ ├── reverseVowelsOfAString.java │ ├── romanToInteger.java │ ├── validPalindrome.java │ └── validParentheses.java ├── Tree │ ├── binaryTreeMaximumPathSum.java │ ├── binaryTreePaths.java │ ├── inorderSuccessorInBST.java │ ├── invertBinaryTree.java │ ├── lowestCommonAncestorOfABinaryTree.java │ ├── sumOfLeftLeaves.java │ └── validateBinarySearchTree.java ├── Trie │ ├── addAndSearchWordDataStructureDesign.java │ ├── implementTrie.java │ └── wordSquares.java └── TwoPointers ├── 3Sum.java ├── 3SumSmaller.java ├── mergeSortedArray.java ├── minimumSizeSubarraySum.java ├── moveZeros.java ├── removeDuplicatesFromSortedArray.java ├── reverseString.java └── sortColors.java 18 directories, 124 files