# 演算法導論 HW11 https://hackmd.io/@wang1234/BJE7IYmDc ## 第1題: shortest path in multi-stage graph <font color="DarkGray" class="small">下圖為一個multi-stage graph,請分別以forward approach與backward approach,推導出點1到12的最短路徑。</font> ![](https://hackmd.io/_uploads/Hy_ZRRnrh.png) ![](https://hackmd.io/_uploads/rJI8xZTB2.png) 最短路徑: 1 → 2 → 7 → 10 → 12 1 → 3 → 6 → 10 → 12 ## 第2題: 計算正方形數量 [1277. Count Square Submatrices with All Ones](https://leetcode.com/problems/count-square-submatrices-with-all-ones/) <font color="Black">解題思路: > ![](https://hackmd.io/_uploads/B1m4Sa0rn.png) (大概知道是這樣的概念,但還無法自行寫出此概念的全部程式碼)</font> ```python= class Solution: def countSquares(self, matrix: List[List[int]]) -> int: m, n = len(matrix), len(matrix[0]) dp = [[0] * (n+1) for _ in range(m+1)] ans = 0 for i in range(m): for j in range(n): if matrix[i][j]: dp[i+1][j+1] = min(dp[i][j+1], dp[i+1][j], dp[i][j]) + 1 ans += dp[i+1][j+1] return ans ``` ![](https://hackmd.io/_uploads/Hylvf2AS3.png) 花60分鐘,抄: [Understandable Python3 DP with Explanation](https://leetcode.com/problems/count-square-submatrices-with-all-ones/solutions/3498069/understandable-python3-dp-with-explanation/) [DP with figure explanation](https://leetcode.com/problems/count-square-submatrices-with-all-ones/solutions/441620/dp-with-figure-explanation/) [Easy to understand](https://leetcode.com/problems/count-square-submatrices-with-all-ones/solutions/2725029/easy-to-understand/) ## 第3題: 所有可能的合法成對括號 [22. Generate Parentheses](https://leetcode.com/problems/generate-parentheses/) <font color="Black">解題思路: > 括號的組成方式可以從數量少一個的組成方式裡推演出來 ![](https://hackmd.io/_uploads/S1-tki0S2.png) 所以我建了一個名為dp的雙層list,dp[0]的裡存放的就是一個括號的組成方式["()"], 當想要查的數量m還沒推導過,dp[m-1]為空列表時,就依上圖的方法去推導,並用轉換set與list的方式去除重複的結果</font> ```python= class Solution: def generateParenthesis(self, n: int) -> List[str]: dp=[ [] for _ in range(n)] dp[0]=["()"] def generate(m): if dp[m-1]!=[]: return dp[m-1] else: temp=set() generate(m-1) for i in dp[m-1-1]: for j in range(len(i)): temp.add(i[:j]+"()"+i[j:]) dp[m-1]=list(temp) return dp[m-1] generate(n) return dp[n-1] ``` ![](https://hackmd.io/_uploads/r1HcEs0r3.png) 花70分鐘,參考: [python code using dp](https://leetcode.com/problems/generate-parentheses/solutions/3152520/python-code-using-dp/) ## 第4題: 巴士卡三角形 [118. Pascal's Triangle](https://leetcode.com/problems/pascals-triangle/) <font color="Black">解題思路: > ![](https://hackmd.io/_uploads/ryXMCo0r2.png) ans為雙層list,存放整個三角形,temp則為每一列編輯時使用, 在for迴圈中往temp內新增元素,例如:在第0圈新增一個1,到第1圈再加入一個1,變成[1,1] ,然後在每圈迴圈的最後把temp新增到ans裡, 但是到第2圈,要編輯ans[2]時,因為ans[2][1]的值,是ans[1][0]和ans[1][1]的和, 所以for迴圈第2圈開始,temp的編輯需要用到上一圈加進ans的內容來計算</font> ```python= class Solution: def generate(self, numRows: int) -> List[List[int]]: ans=[] temp=[] for i in range(numRows): if i>=2: for j in range(len(temp)): if j>=1: temp[j]=ans[-1][j-1]+ans[-1][j] temp.append(1) ans.append(list(temp)) return ans ``` ![](https://hackmd.io/_uploads/S1fdEo0B2.png) 花40分鐘,完全靠自己 ## 第4題: 存積雨水 [392. Is Subsequence](https://leetcode.com/problems/is-subsequence/) <font color="Black">解題思路: > 在每次的函式呼叫中傳入子序列s和目標序列t, 抓子序列的第一個字元s[0],用find函式在t中尋找, 當在t中找不到時(返回值=-1),return False; 當有找到時,返回值為s在t中的位置索引值x,將s扣除已找到的第一位以及t在索引值x後面的剩餘字串傳入遞迴, 直到參數s接收到的是空字串,表示原本子序列裡的字元都已依序在目標序列中找到,so return True</font> ```python= class Solution: def isSubsequence(self, s: str, t: str) -> bool: if s=='': return True x=t.find(s[0]) if x==-1: return False else: return self.isSubsequence(s[1:],t[x+1:]) ``` ![](https://hackmd.io/_uploads/Sk_44sRH2.png) 花30分鐘,求助: [python 遞迴呼叫返回None的問題及解決方法_程式設計_程式人生](https://www.796t.com/article.php?id=16458) ## 心得 最後兩題雖然有寫出能pass的程式碼,但自己都有點疑惑是否是用到了dynamic programming的概念