极客时间 算法训练营 毕业总结
不知不覺8周的算法訓練營也接近尾聲,這期間訓練營對自己的影響有三方面
- 一方面是收獲了刻意練習,終身成長這些可以產生長遠影響的思想,這里推薦三本書 卡羅爾·德韋克的《終身成長》、安德斯·艾利克森和羅伯特·普爾的《刻意練習》以及彼得·布朗等的《認知天性》
- 一方面是在自己對算法與數據結構的態度與認知上,從之前的抗拒和一提到就覺得很難,到接受和樂在其中的轉變,從算法與數據結構大概是這樣,到有一個脈絡清晰的知識結構的轉變
- 一方面就是知識本身,下面將數據結構與算法總體回顧下
數據結構
一維
- 基礎: 數組 array (string),鏈表 linked list
- 高級: 棧 stack,隊列 queue,雙端隊列 deque,集合 set,映射 map (hash or map),etc
涉及題目:
棧 stack: 括號匹配問題、直方圖、接雨水
隊列 queue: 滑動窗口
二維
- 基礎: 樹 tree,圖 graph
- 高級: 二叉搜索樹 binary search tree (red-black tree,AVL),堆 heap,并查集 disjoint set,字典樹 Trie,etc
特殊
- 位運算 Bitwise,布隆過濾器 BloomFilter
- LRU Cache
時間復雜度圖
https://www.bigocheatsheet.com/
主定理
https://en.wikipedia.org/wiki/Master_theorem_(analysis_of_algorithms)
- 一維數組二分查找:每次排除一半,故為O(log n)
- 二叉樹的遍歷:可以理解成每個節點被訪問且僅訪問一次,故為O(n)
- 二維矩陣的二分查找:O(n)
- 歸并排序:O(n logn)
數據結構思維導圖
算法
- if-else,switch ——> branch
- for,while loop ——> literation
- 遞歸 Recursion (Divide & Conquer ,Backtrace)
所有高級算法或數據結構最后都會轉換成以上三種
- 搜索 Search:深度優先搜索 Depth first search, 廣度優先搜索 Breadth first search,A*,etc
- 動態規劃 Dynamic Programming (遞歸+備忘錄 或 迭代+DP方程)
- 二分查找 Binary Search
- 貪心 Greedy
- 數學 Math,幾何 Geometry
算法 思維導圖
鏈接:https://pan.baidu.com/s/1FL93CnqsWA0jbHt_ePSpjQ
提取碼:ulud
代碼模板
這里列舉部分模板,其他模板 并查集 Disjoint Set、布隆過濾器、LRU Cache、初級排序、特殊排序等模板可以參看之前總結
遞歸模板
def recursion(level, param1, param2, ...): # 遞歸終止條件if level > MAX_LEVEL: process_result return # 處理當前層邏輯process(level, data...) # 往下一層self.recursion(level + 1, p1, ...) # 清理當前層分治模板
def divide_conquer(problem, param1, param2, ...): # 遞歸終止條件if problem is None: print_result return # 處理當前層邏輯(分解子問題)data = prepare_data(problem) subproblems = split_problem(problem, data) # 往下一層(解決子問題)subresult1 = self.divide_conquer(subproblems[0], p1, ...) subresult2 = self.divide_conquer(subproblems[1], p1, ...) subresult3 = self.divide_conquer(subproblems[2], p1, ...) …# 合并子結果(合并結果)result = process_result(subresult1, subresult2, subresult3, …)# 清理當前層歸并排序模板
def merge_sort(arr, left, right):"""歸并排序(Merge Sort)"""if right <= left: # 遞歸終止條件return# 先輸入序列分成兩個長度為n/2的子序列并對這兩個子序列分別采用歸并排序mid = (left + right) >> 1 # (left + right) / 2merge_sort(arr, left, mid) # 注意 midmerge_sort(arr, mid + 1, right)# 排序好的子序列合, 重點 merge 函數的實現merge(arr, left, mid, right)def merge(arr, left, mid, right):# left , mid 有序 mid + 1 , right 有序temp = [0 for _ in range( right - left + 1)] # 中間數組, 需要額外的內存空間i = leftj = mid + 1k = 0while i <= mid and j <= right: # 合并 left , mid 有序數列 和 mid + 1 , right 有序數列if arr[i] <= arr[j]:temp[k] = arr[i]k, i = k + 1, i + 1else:temp[k] = arr[j]k, j = k + 1, j + 1while i <= mid: # left , mid 有序數列 剩余temp[k] = arr[i]k, i = k + 1, i + 1while j <= right: # mid + 1 , right 有序數列 剩余temp[k] = arr[j]k, j = k + 1, j + 1# 將 排序好的 temp 放入 arr 中for p in range(len(temp)):arr[left + p] = temp[p]快速排序模板
def quick_sort(arr, begin, end):"""快速排序(Quick Sort)"""if end <= begin: # 遞歸終止條件return# 先找標桿 pivot,將小元素放 pivot左邊,大元素放右側; 重點 partition 函數的實現pivot = partition(arr, begin, end)# 然后依次對標桿 pivot 右邊和右邊的子數組繼續快排quick_sort(arr, begin, pivot-1) # 注意 不包括標桿quick_sort(arr, pivot + 1,end)def partition(arr, begin, end):"""partition 函數 用于查找 標桿位置并處理排序數組"""pivot = end # 選擇 end 為標桿min_index = begin # counter: ?于pivot的元素的下標for i in range(begin, end): # 這里不包含 標桿位置if arr[i] < arr[pivot]: # i 位置數據 小于 a[pivot]arr[min_index], arr[i] = arr[i], arr[min_index] # 交換 arr[min_index], arr[i] 數據位置min_index += 1 # 遞增# 循環結束 min_index 就為 標桿應該所在位置arr[min_index], arr[pivot] = arr[pivot], arr[min_index]return min_indexDFS 模板
遞歸實現:
#遞歸前處理 visited = set() # 節點是否被訪問def dfs(node,visited):# 遞歸終止條件if node in visited: # 是否被訪問return# 遞歸到下一層前處理(當前層處理)visited.add(node) # 其它處理# 遞歸到下一層for next_node in node.children(): if not next_node in visited: dfs(next_node, visited)# 遞歸下層次返回后處理迭代實現:
dfs=棧,壓棧,出棧
BFS 模板
迭代實現:
bfs=隊列,入隊列,出隊列
def bfs(graph, start, end):# 迭代前處理queue = [] # 輔助隊列queue.append([start]) # 入隊列visited.add(node) # 標記訪問# 迭代終止條件while queue:# 迭代 node = queue.pop(0) # 出隊列visited.add(node) # 標記訪問rocess (node) # 當前節點處理nodes = generate_related_nodes(node) # 生成相關節點queue.push(nodes) # 入隊列# 迭代后處理二分查找代碼模板
left, right = 0, len(array) - 1 while left <= right: # mid = (left + right) / 2mid = low + (high-low)/2if array[mid] == target: # 找到目標break or return result elif array[mid] < target: left = mid + 1 else: right = mid - 1Trie樹模板
class Trie:def __init__(self):self.root = {} # 根節點self.endofword = "#" # 標識是否是一個完整的單詞def insert(self, word: str) -> None:# 插入操作node = self.root # 根節點for char in word: # 遍歷單詞 word 中每個字符node = node.setdefault(char,{}) # 字典形式依次將字符保存到樹的每一層中# dict.setdefault(key, default=None) 如果 key 在 字典中,返回對應的值。# 如果不在字典中,則插入 key 及設置的默認值 default,并返回 default ,default 默認值為 None。node[self.endofword] = self.endofword # 完整單詞標識def search(self, word: str) -> bool:# 查找操作node = self.rootfor char in word: # 遍歷單詞 word 中每個字符if char not in node: # 未找到return Falsenode = node.get(char) # 找到進入下一結點return self.endofword in node # 是否為完整的單詞def startsWith(self, prefix: str) -> bool:# 字典樹中是否有以 prefix 為前綴的單詞node = self.rootfor char in prefix: # 遍歷 前綴 prefixif char not in node:return Falsenode = node.get(char) return True學習要點
基本功是區別業余和職業選手的根本。深厚功底來自于 — 過遍數
最大的誤區:只做一遍
五毒神掌
刻意練習 - 練習缺陷弱點地方、不舒服、枯燥
反饋 - 看題解、看國際版的高票回答
切題四件套
- Clarification
- Possible Solutions
- compare (time/space)
- optimal (加強)
- Coding(多寫)
- Test cases
五毒神掌
第一遍
五分鐘:讀題 + 思考
直接看解法:多看幾種,比較解法優劣
背誦、默寫好的解法
第二遍
馬上自己寫 ——> Leetcode提交
多種解法比較、體會 ——> 優化!
第三遍
過了一天后,再重復做題
不同解法的熟練程度——>專項練習
第四遍
過了一周后:反復回來練習相同的題目
第五遍
面試前一周恢復性訓練
經典習題
爬樓梯: https://leetcode-cn.com/problems/climbing-stairs/
硬幣兌換: https://leetcode-cn.com/problems/coin-change/
有效括號: https://leetcode-cn.com/problems/valid-parentheses/
括號生成: https://leetcode-cn.com/problems/generate-parentheses/
柱狀圖中最大的矩形: https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
滑動窗口最大值: https://leetcode-cn.com/problems/sliding-window-maximum/
二叉樹遍歷:
- 二叉樹的層次遍歷:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
- 二叉樹的前序遍歷: https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
- 二叉樹的中序遍歷: https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
- 二叉樹的后序遍歷: https://leetcode-cn.com/problems/binary-tree-postorder-traversal/
驗證二叉搜索樹: https://leetcode-cn.com/problems/validate-binary-search-tree/submissions/
股票買賣:
- 買賣股票的最佳時機 IV https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-iv/
打家劫舍:
- 打家劫舍 II: https://leetcode-cn.com/problems/house-robber-ii/
編輯距離: https://leetcode-cn.com/problems/edit-distance/
最長上升子序列: https://leetcode-cn.com/problems/longest-increasing-subsequence/
最長公共子序列: https://leetcode-cn.com/problems/longest-common-subsequence/
字母異位詞分組: https://leetcode-cn.com/problems/group-anagrams/
回文串:
- 最長回文子串: https://leetcode-cn.com/problems/longest-palindromic-substring/
通配符匹配: https://leetcode-cn.com/problems/wildcard-matching/
高級數據結構(Trie、 BloomFilter、 LRU cache、 etc)
總結
以上是生活随笔為你收集整理的极客时间 算法训练营 毕业总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AutoCAD实用小技巧教程。
- 下一篇: 基于C语言的双人贪吃蛇游戏程序设计