軟件工程技術面試我的指南

在 github 上發現這麼一篇,感受不錯,分享出來。java

原文地址:https://github.com/kdn251/interviews/blob/master/README-zh-cn.mdandroid

目錄

在線練習

在線面試編程

數據結構

Linked List

  • 鏈表便是由節點(Node)組成的線性集合,每一個節點能夠利用指針指向其餘節點。它是一種包含了多個節點的、可以用於表示序列的數據結構。
  • 單向鏈表: 鏈表中的節點僅指向下一個節點,而且最後一個節點指向空。
  • 雙向鏈表: 其中每一個節點具備兩個指針 p、n,使得 p 指向先前節點而且 n 指向下一個節點;最後一個節點的 n 指針指向 null。
  • 循環鏈表:每一個節點指向下一個節點而且最後一個節點指向第一個節點的鏈表。
  • 時間複雜度:
    • 索引: O(n)
    • 搜索: O(n)
    • 插入: O(1)
    • 移除: O(1)

Stack

  • 棧是元素的集合,其包含了兩個基本操做:push 操做能夠用於將元素壓入棧,pop 操做能夠將棧頂元素移除。
  • 遵循後入先出(LIFO)原則。
  • 時間複雜度:
  • 索引: O(n)
  • 搜索: O(n)
  • 插入: O(1)
  • 移除: O(1)

Queue

  • 隊列是元素的集合,其包含了兩個基本操做:enqueue 操做能夠用於將元素插入到隊列中,而 dequeeu 操做則是將元素從隊列中移除。
  • 遵循先入先出原則 (FIFO)。
  • 時間複雜度:
  • 索引: O(n)
  • 搜索: O(n)
  • 插入: O(1)
  • 移除: O(1)

Tree

  • 樹是無向、連通的無環圖。

Binary Tree

  • 二叉樹便是每一個節點最多包含左子節點與右子節點這兩個節點的樹形數據結構。
  • 滿二叉樹: 樹中的每一個節點僅包含 0 或 2 個節點。
  • 完美二叉樹(Perfect Binary Tree): 二叉樹中的每一個葉節點都擁有兩個子節點,而且具備相同的高度。
  • 徹底二叉樹: 除最後一層外,每一層上的結點數均達到最大值;在最後一層上只缺乏右邊的若干結點。

Binary Search Tree

  • 二叉搜索樹(BST)是一種特殊的二叉樹,其任何節點中的值都會大於或者等於其左子樹中存儲的值而且小於或者等於其右子樹中存儲的值。
  • 時間複雜度:
    • 索引: O(log(n))
    • 搜索: O(log(n))
    • 插入: O(log(n))
    • 刪除: O(log(n))

Binary Search Tree

Trie

  • 字典樹,又稱基數樹或者前綴樹,可以用於存儲鍵爲字符串的動態集合或者關聯數組的搜索樹。樹中的節點並無直接存儲關聯鍵值,而是該節點在樹中的掛載位置決定了其關聯鍵值。某個節點的全部子節點都擁有相同的前綴,整棵樹的根節點則是空字符串。

Alt text

Fenwick Tree

  • 樹狀數組又稱 Binary Indexed Tree,其表現形式爲樹,不過本質上是以數組實現。數組中的下標表明着樹中的頂點,每一個頂點的父節點或者子節點的下標可以經過位運算得到。數組中的每一個元素包含了預計算的區間值之和,在整棵樹更新的過程當中一樣會更新這些預計算的值。
  • 時間複雜度:
    • 區間求值: O(log(n))
    • 更新: O(log(n))

Alt text

Segment Tree

  • 線段樹是用於存放間隔或者線段的樹形數據結構,它容許快速的查找某一個節點在若干條線段中出現的次數.
  • 時間複雜度:
    • 區間查詢: O(log(n))
    • 更新: O(log(n))

Alt text

Heap

  • 堆是一種特殊的基於樹的知足某些特性的數據結構,整個堆中的全部父子節點的鍵值都會知足相同的排序條件。堆更準確地能夠分爲最大堆與最小堆,在最大堆中,父節點的鍵值永遠大於或者等於子節點的值,而且整個堆中的最大值存儲於根節點;而最小堆中,父節點的鍵值永遠小於或者等於其子節點的鍵值,而且整個堆中的最小值存儲於根節點。
  • 時間複雜度:
    • 訪問: O(log(n))
    • 搜索: O(log(n))
    • 插入: O(log(n))
    • 移除: O(log(n))
    • 移除最大值 / 最小值: O(1)

Max Heap

Hashing

  • 哈希可以將任意長度的數據映射到固定長度的數據。哈希函數返回的便是哈希值,若是兩個不一樣的鍵獲得相同的哈希值,即將這種現象稱爲碰撞。
  • Hash Map: Hash Map 是一種可以創建起鍵與值之間關係的數據結構,Hash Map 可以使用哈希函數將鍵轉化爲桶或者槽中的下標,從而優化對於目標值的搜索速度。
  • 碰撞解決
    • 鏈地址法(Separate Chaining): 鏈地址法中,每一個桶是相互獨立的,包含了一系列索引的列表。搜索操做的時間複雜度便是搜索桶的時間(固定時間)與遍歷列表的時間之和。
    • 開地址法(Open Addressing): 在開地址法中,當插入新值時,會判斷該值對應的哈希桶是否存在,若是存在則根據某種算法依次選擇下一個可能的位置,直到找到一個還沒有被佔用的地址。所謂開地址法也是指某個元素的位置並不永遠由其哈希值決定。

Alt text

Graph

  • 圖是一種數據元素間爲多對多關係的數據結構,加上一組基本操做構成的抽象數據類型。
    • 無向圖(Undirected Graph): 無向圖具備對稱的鄰接矩陣,所以若是存在某條從節點 u 到節點 v 的邊,反之從 v 到 u 的邊也存在。
    • 有向圖(Directed Graph): 有向圖的鄰接矩陣是非對稱的,即若是存在從 u 到 v 的邊並不意味着必定存在從 v 到 u 的邊。

Graph

算法

排序

快速排序

  • 穩定: 否
  • 時間複雜度:
    • 最優時間: O(nlog(n))
    • 最壞時間: O(n^2)
    • 平均時間: O(nlog(n))

Alt text

歸併排序

  • 歸併排序是典型的分治算法,它不斷地將某個數組分爲兩個部分,分別對左子數組與右子數組進行排序,而後將兩個數組合併爲新的有序數組。
  • 穩定: 是
  • 時間複雜度:
    • 最優時間: O(nlog(n))
    • 最壞時間: O(nlog(n))
    • 平均時間: O(nlog(n))

Alt text

桶排序

  • 桶排序將數組分到有限數量的桶子裏。每一個桶子再個別排序(有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序進行排序)。
  • 時間複雜度:
    • 最優時間: Ω(n + k)
    • 最壞時間: O(n^2)
    • 平均時間:Θ(n + k)

Alt text

基數排序

  • 基數排序相似於桶排序,將數組分割到有限數目的桶中;不過其在分割以後並無讓每一個桶單獨地進行排序,而是直接進行了合併操做。
  • 時間複雜度:
    • 最優時間: Ω(nk)
    • 最壞時間: O(nk)
    • 平均時間: Θ(nk)

圖算法

深度優先搜索

  • 深度優先算法是一種優先遍歷子節點而不是回溯的算法。
  • 時間複雜度: O(|V| + |E|)

Alt text

廣度優先搜索

  • 廣度優先搜索是優先遍歷鄰居節點而不是子節點的圖遍歷算法。
  • 時間複雜度: O(|V| + |E|)

Alt text

拓撲排序

  • 拓撲排序是對於有向圖節點的線性排序,若是存在某條從 u 到 v 的邊,則認爲 u 的下標先於 v。
  • 時間複雜度: O(|V| + |E|)

Dijkstra 算法

  • Dijkstra 算法 用於計算有向圖中單源最短路徑問題。
  • 時間複雜度: O(|V|^2)

Alt text

Bellman-Ford 算法

  • Bellman-Ford 算法是在帶權圖中計算從單一源點出發到其餘節點的最短路徑的算法。
  • 儘管算法複雜度大於 Dijkstra 算法,可是它適用於包含了負值邊的圖。
  • 時間複雜度:
    • 最優時間: O(|E|)
    • 最壞時間: O(|V||E|)

Alt text

Floyd-Warshall 算法

  • Floyd-Warshall 算法 可以用於在無環帶權圖中尋找任意節點的最短路徑。
  • 時間複雜度:
    • 最優時間: O(|V|^3)
    • 最壞時間: O(|V|^3)
    • 平均時間: O(|V|^3)

Prim 算法

  • Prim 算法是用於在帶權無向圖中計算最小生成樹的貪婪算法。換言之,Prim 算法可以在圖中抽取出鏈接全部節點的邊的最小代價子集。
  • 時間複雜度: O(|V|^2)

Alt text

Kruskal 算法

  • Kruskal 算法一樣是計算圖的最小生成樹的算法,與 Prim 的區別在於並不須要圖是連通的。
  • 時間複雜度: O(|E|log|V|)

Alt text

位運算

  • 位運算便是在位級別進行操做的技術,合適的位運算可以幫助咱們獲得更快地運算速度與更小的內存使用。
  • 測試第 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)
  • 取出最小非 0 位(Extract lowest set bit): s & (-s)
  • 取出最小 0 位(Extract lowest unset bit): ~s & (s + 1)
  • 交換值: x ^= y; y ^= x; x ^= y;

算法複雜度分析

大 O 表示

  • 大 O 表示 用於表示某個算法的上限,每每用於描述最壞的狀況。

Alt text

小 O 表示

  • 小 O 表示用於描述某個算法的漸進上界,不過兩者要更爲緊密。

大 Ω 表示

  • 大 Ω 表示用於描述某個算法的漸進下界。

Alt text

小 ω 表示

  • Little Omega Notation用於描述某個特定算法的下界,不過不必定很靠近。

Theta Θ 表示

  • Theta Notation用於描述某個肯定算法的確界。

Alt text

視頻教程

面試書籍

  • 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
相關文章
相關標籤/搜索