# <font size=12 color=skyblue>從LeetCode學演算法</font> Chihyu Lin <!-- Put the link to this slide here so people can follow --> Slide: https://hackmd.io/@Desolve/SJi7bBjXH --- <font size=5>We will have some practices on LeetCode. Please prepare your laptop and register LeetCode account first.</font> --- ## <font size=7 color=skyblue>Who am I?</font> - <font size=6>Senior Software Engineer at ASUS (2013.03-2019.07) </font> - <font size=6>AI Engineer at Libgirl (Now)</font> - <font size=6>Have a cat :cat:</font> - <font size=6>Write a series of [從LeetCode學演算法](https://medium.com/@desolution/%E5%BE%9Eleetcode%E5%AD%B8%E6%BC%94%E7%AE%97%E6%B3%95-0-6c121bd8b579) to share algorithms from LeetCode</font> --- ## <font size=7 color=skyblue>Introduction</font> --- ### <font size=7 color=skyblue>Why do we need to learn algorithms?</font> - <font size=6>你/妳有以下的<font color=violet>「症頭」</font>嗎?</font> -- <font size=6>明明有準備,面對白板<font color=green>腦袋卻一片空白</font>?</font> -- <font size=6><font color=skyblue>題目類型好眼熟</font>,但我該從哪裡開始下手QQ</font> -- <font size=6>明明說是問經歷怎麼開始問<font color=red>演算法</font>?</font> - <font size=6>所有程式類面試幾乎都會問<font color=violet>白板題</font></font> - <font size=6>而白板題的重點就在於<font color=violet>演算法</font></font> -- <font size=6>就像數學學會公式一樣</font> -- <font size=6>練習的題目多了,套公式就能得心應手!</font> --- ### <font size=7 color=skyblue>Why LeetCode?</font> - <font size=6>其實有很多可以練習Coding的網站</font> -- <font size=6><font color=violet>HackerRank</font> -> 熟悉語言,題目較長</font> -- <font size=6><font color=violet>CodeWar</font> -> 偏向打怪升級</font> - <font size=6><font color=violet>LeetCode</font>的編號較明確,每個題目的討論區也很踴躍</font> -- <font size=6>Easy難度寫過一輪</font> -- <font size=6>搭配少量Medium和Hard,足以應付絕大多數的白板題</font> - <font size=5>Don't fail at interviews first, then realize the whiteboard part is important.</font> --- ### <font size=7 color=skyblue>How to practice?</font> - <font size=6>自己先嘗試兜出解法</font> - <font size=6>能力範圍內盡力提升這個解法的執行速度</font> - <font size=6>真的不行或卡超過半小時才參考別人的解答</font> - <font size=6>練習到一定程度後即可將注意力集中在目標相關的領域</font> --- ### <font size=6 color=skyblue>Before we start, something you need to know</font> - <font size=6 color=violet>Time/Space Complexity (時間/空間複雜度)</font> -- <font size=6>使用O()表示法 (Big-O)</font> -- <font size=6>只考慮<font color=skyblue>最高項</font></font> -- <font size=6>通常會假設輸入的長度為N,其耗費的時間/空間複雜度來表示</font> -- <font size=6>來嘗試看看一些例子吧!</font> -- <font size=6>註: 下面的範例均假定<font color=skyblue>N大於0</font></font> --- - <font size=6 color=skyblue>請問下列程式碼的時間複雜度為何?</font> ``` Python def forLoop(N): sum = 0 for i in range(N): sum += i*i return sum ``` --- - <font size=6 color=skyblue>請問下列程式碼的時間複雜度為何?</font> ``` Python def forLoop(N): sum = 0 for i in range(N): if i > 5: break else: sum += i*i return sum ``` --- - <font size=6 color=skyblue>請問下列程式碼的時間複雜度為何?</font> ``` Python def nestedForLoop(N): sum = 0 for i in range(N): for j in range(i, N): sum += i * j return sum ``` --- ### <font size=7 color=skyblue>Let's start!</font> - https://leetcode.com/ - Remember to login/register first - Let's go for first example: [0001 Two Sum](https://leetcode.com/problems/two-sum/) --- ## <font size=7 color=skyblue>Examples</font> --- ### <font size=7 color=skyblue>Example 1: [0001. Two Sum (Easy)](https://leetcode.com/problems/two-sum/) </font><font size=6>(Dictionary/HashMap)</font> --- ![](https://i.imgur.com/9xq86I8.png) --- - <font size=6 color=skyblue>Brute Force: O(N^2)</font> -- <font size=6>每次固定一個值</font> -- <font size=6>拿其他的值和它相加,檢查結果</font> --- - <font size=6 color=skyblue>Dictionary/HashMap</font> -- <font size=6>key, value兩兩相對</font> -- <font size=6><font color=violet>單一key值只會對應到一個value</font></font> --- - <font size=6 color=skyblue>Using Dictionary</font> -- <font size=6>檢查key值: O(1)</font> -- <font size=6>將值放入: O(1)</font> -- <font size=6>最多放入N-1對 -> 所以總複雜度為<font color=violet>O(N)</font></font> --- - <font size=6 color=skyblue>Problem Solving</font> -- <font size=6>依序檢查<font color=violet>target-nums[i]</font>有沒有在dict中</font> -- <font size=6>有的話取出對應indices回傳</font> -- <font size=6>沒有的話將<font color=violet>(nums[i], i)</font>放進dict裡</font> --- - <font size=6 color=skyblue>Try it!</font> --- {%gist Desolve/e936fe7cbad8aa7810eeffacebadda41%} --- - <font size=6 color=skyblue>備註:</font> -- <font size=6><font color=violet>dict.__ contains __</font>的寫法,也可以改用<font color=violet>key in dict</font>的方式</font> - <font size=6 color=skyblue>思考一下</font> -- <font size=6>如果題目要求找出所有的解呢?</font> --- ### <font size=7 color=skyblue>Example 2: [0035. Search Insert Position](https://leetcode.com/problems/search-insert-position/) </font> <font size=6>(Binary Search)</font> --- ![](https://i.imgur.com/08qtrJs.png) --- - <font size=6 color=skyblue>Brute Force: O(N)</font> -- <font size=6>從頭開始找,當target比nums[i]<font color=violet>大就繼續往下</font> -- <font size=6>當target比nums[i]小就進行回傳</font> -- <font size=6>當target和nums[i]相等也進行回傳</font> -- <font size=6>如果走到尾端的話,代表應該插入在尾端</font> --- - <font size=6 color=skyblue>Binary Search(二元搜尋法)</font> -- <font size=6>利用陣列<font color=violet>已排序</font>的特性</font> -- <font size=6>將邊界設定成<font color=violet>lo = 0, up = l-1</font> (l是nums的長度)</font> -- <font size=6>先取中間點<font color=violet>mi=(lo+up)//2</font>,比較nums[mi]和target的大小</font> -- <font size=6 color=violet>若兩者相等 -> 找到正確值了,回傳mi</font> --- - <font size=6 color=skyblue>Binary Search(二元搜尋法)</font> -- <font size=6><font color=violet>若nums[mi] > target </font> -> 表示目標應該在<font color=violet>lo和mi之間(不含mi)</font></font> -- <font size=6><font color=violet>若nums[mi] < target </font> -> 表示目標應該在<font color=violet>mi和up之間(不含mi)</font></font> -- <font size=6>反覆調整直到相等或兩者交錯(此時<font color=skyblue>插入的位置應在lo處</font>)</font> -- <font size=6>每次都要將lo或up其中之一更新,從而改變mi</font> --- - <font size=6 color=skyblue>Try it!</font> --- {%gist Desolve/97cea741906acfed250c644a263524df%} --- - <font size=6 color=skyblue>思考一下</font> -- <font size=6>時間複雜度是多少呢?</font> - <font size=6>(相似題: [0704. Binary Search(Easy)](https://leetcode.com/problems/binary-search/))</font> --- ### <font size=7 color=skyblue>Example 3: [0100. Same Tree (Easy)](https://leetcode.com/problems/same-tree/) </font> <font size=6>(Binary Tree)</font> --- ![](https://i.imgur.com/vMjMz4F.png) --- - <font size=6 color=skyblue>Binary Tree (二元樹)</font> -- <font size=6>root/left/right node</font> -- <font size=6>NIL(None/null)</font> -- <font size=6>Each node contains a value</font> -- <font size=6>Each node has its left node and right node</font> - <font size=6 color=skyblue>兩棵樹相同?</font> -- <font size=6>結構一樣(沒有多長,也沒有少長)</font> -- <font size=6>相同位置的值也一樣</font> --- - <font size=6 color=skyblue>遞迴(recursion)</font> -- <font size=6>透過不斷<font color=violet>呼叫相同的函式</font>,將問題化簡最終得到答案的方法。</font> -- <font size=6>要有<font color=violet>確定狀況</font>的條件及<font color=violet>前後連結</font>的關係</font> -- <font size=6>例如: n+(n-1)+(n-2)+...+1?</font> ``` Python def sumN(n): if n == 1: # 確定狀況的條件,不然會一直往下減下去 return 1 else: return n + sumN(n-1) ``` --- - <font size=6 color=skyblue>對一棵二元樹而言</font> -- <font size=6>左節點及其下面的所有節點可構成一棵二元樹</font> -- <font size=6>同理右節點也可以構成一棵二元樹</font> - <font size=6 color=skyblue>比較兩棵二元樹是否相等,等同於比較:</font> <font size=6>1. root是否<font color=skyblue>同時存在</font>或<font color=skyblue>同時不存在</font>,同時存在的話,<font color=skyblue>值必須相等</font></font> <font size=6>2. 同時存在且值相等的話,其左子樹和右子樹再各自進行比較</font> <font size=6>3. 左右子樹也都分別相等的話,則二棵二元樹相等</font> --- - <font size=6 color=skyblue>Try it!</font> ``` Python # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None ``` --- {%gist Desolve/47039932c601895037c316bc7bec1842%} --- - <font size=6 color=skyblue>思考一下</font> -- <font size=6>時間複雜度是多少呢?</font> -- <font size=6>如果換成想檢查兩棵樹是否互相為彼此的<font color=violet>鏡像</font>該怎麼解?</font> - <font size=6>(相似題: [0101. Symmetric Tree](https://leetcode.com/problems/symmetric-tree/))</font> --- ### <font size=7 color=skyblue>Example 4: [0070. Climbing Stairs (Easy)](https://leetcode.com/problems/climbing-stairs/) </font> <font size=6>(Dynamic Programming)</font> --- ![](https://i.imgur.com/VwNnUKx.png) --- - <font size=6 color=skyblue>動態規劃 (Dynamic Programming)</font> -- <font size=6>目標不容易直接透過簡單計算處理</font> -- <font size=6>但走到第n階的結果,可能可以用走到n-1, n-2階的結果來表達</font> -- <font size=6>且第1階/第2階的結果可以直接得到</font> -- <font size=6>透過迴圈一路走上來</font> --- - <font size=6>走到第1階的方法數? 1種 (0->1)</font> - <font size=6>走到第2階的方法數? 2種 (0->1->2 or 0->2)</font> - <font size=6>走到第n階的方法數? 等於走到<font color=violet>第n-2階的方法數+走到第n-1階的方法數</font></font> --- - <font size=6 color=skyblue>Try it!</font> --- {%gist Desolve/36f7e5bd29cd65347e68e9617b6c8b30%} --- - <font size=6 color=skyblue>思考一下</font> -- <font size=6>時間複雜度是多少呢?</font> -- <font size=6>它的結果其實跟一個很著名的數列一致XD</font> --- ### <font size=7 color=skyblue>Example 5: [0198. House Robber (Easy)](https://leetcode.com/problems/house-robber/) </font> <font size=6>(Dynamic Programming)</font> --- ![](https://i.imgur.com/7O8pIyF.png) --- - <font size=6 color=skyblue>相鄰房子不能被偷</font> -- <font size=6>要偷第i-1棟房子的話,就不能偷第i棟</font> -- <font size=6>如果設定偷到第i棟的最大收益是rob[i]的話</font> -- <font size=6>rob[i], rob[i-1], rob[i-2], nums[i]之間有何關係?</font> --- - <font size=6 color=skyblue>兩個狀況選其一時,按題目條件要取比較大的</font> -- <font size=6>rob[i] = max(nums[i] + rob[i-2], rob[i-1])</font> - <font size=6 color=skyblue>起始條件?</font> -- <font size=6>rob[0] = nums[0]</font> -- <font size=6>rob[1] = ?</font> --- - <font size=6 color=skyblue>Try it!</font> --- {%gist Desolve/d83c7c68910e5e456a511e45fa32f743%} --- - <font size=6 color=skyblue>思考一下</font> -- <font size=6>時間複雜度是多少呢?空間複雜度又是多少?</font> -- <font size=6>空間複雜度能化簡嗎?</font> -- <font size=6>如果今天房子被建造成<font color=violet>圓形分布</font>, 也就是第一棟跟最後一棟相鄰呢?</font> - <font size=6>(延伸題: [0213. House Robber II](https://leetcode.com/problems/house-robber-ii/))</font> --- ### <font size=7 color=skyblue>Wrap up</font> - <font size=6>Practice your coding <font color=blue>basic skill first</font></font> - <font size=6>Try to solve problems and <font color=blue>understand the algorithm you use</font></font> - <font size=6>Don't be afraid of asking</font> - <font size=6>Polish up your domain skill</font> - <font size=6 color=violet>Happy coding!</font> --- ### <font size=7 color=skyblue>Thank you! :tada: </font> - <font size=6>You can find me on</font> -- <font size=6>[Medium](https://medium.com/@desolution)</font> -- <font size=6>[Python Taiwan](https://www.facebook.com/groups/pythontw/) (I'll share my articles there)</font> -- <font size=6>or [email me](mailto:fp60403+happy.coding@gmail.com)</font> - <font size=6>If you're interested in <font color=violet>MLOps solution</font> for AI</font> -- <font size=6>Come and try our platform [dong](https://dong.libgirl.com/)!</font> - <font size=6>Q&A</font>
{"metaMigratedAt":"2023-06-14T23:20:12.597Z","metaMigratedFrom":"YAML","title":"從LeetCode學演算法","breaks":true,"description":"View the slide with \"Slide Mode\".","slideOptions":"{\"theme\":\"black\"}","contributors":"[{\"id\":\"0cd4dda9-fdba-4aa5-87b3-b67e318be738\",\"add\":12407,\"del\":3514}]"}
    926 views