# <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>
---

---
- <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>
---

---
- <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>
---

---
- <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>
---

---
- <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>
---

---
- <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}]"}