# 演算法導論 HW10 https://hackmd.io/@wang1234/HkWbPrqI5 ## 第1題: 01背包問題 ![](https://hackmd.io/_uploads/By8kOBSSh.png) ![](https://hackmd.io/_uploads/HkYl_BSB2.png) ![](https://hackmd.io/_uploads/Hkab_SSH2.png) ![](https://hackmd.io/_uploads/HyGmuBHHh.png) ![](https://hackmd.io/_uploads/S1BNurrrn.png) ## 第2題: A* 解multi-stage shortest path problem <font color="DarkGray" class="small">請使用A* 找出S到T的最短路徑。請畫出樹狀圖,並標示各點的cost,並註明哪裏分枝不用再繼續尋找了。</font> ![](https://hackmd.io/_uploads/ryZpUBLHn.png) 最短路徑: S → C → F → T ## 第3題: Channel Routing Problem ![](https://hackmd.io/_uploads/r16mxtUHn.png) <font color="DarkGray" class="small">請使用A* 解Channel Routing Problem。 請找出最少track的安排方式。</font> | ![](https://hackmd.io/_uploads/S1Y3y_LB2.png) | ![](https://hackmd.io/_uploads/S1l6EOUS3.png) | | -------- | -------- | ![](https://hackmd.io/_uploads/r1VelYLS2.png) 最少track的安排方式: {8,1} → {3,2} → {5} → {4,6} ## 第4題: 合併二元樹 [617. Merge Two Binary Trees](https://leetcode.com/problems/merge-two-binary-trees/) <font color="Black">解題思路: > 當tree_1和tree_2都已沒有節點(已達終端),return None; > 或者tree_1和tree_2的只剩其一有節點,將節點的值用來建合併樹的節點,然後在遞迴中沒有節點的樹就傳None; > 若是tree_1和tree_2都還存在節點,合併樹的節點值為兩節點值的和</font> ```python= class Solution: def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]: def merge(tree_1,tree_2): if not tree_1 and not tree_2: return None if not tree_1: m=TreeNode(tree_2.val) m.left= merge(None , tree_2.left) m.right= merge(None , tree_2.right) elif not tree_2: m=TreeNode(tree_1.val) m.left= merge(tree_1.left , None) m.right= merge(tree_1.right , None) else: m=TreeNode(tree_1.val + tree_2.val) m.left= merge(tree_1.left , tree_2.left) m.right= merge(tree_1.right , tree_2.right) return m return merge(root1,root2) ``` ![](https://hackmd.io/_uploads/SJqWvKUBn.png) 花30分鐘,完全靠自己 ## 第5題: 最深葉子的最低共同祖先 [1123. Lowest Common Ancestor of Deepest Leaves](https://leetcode.com/problems/lowest-common-ancestor-of-deepest-leaves/) <font color="Black">解題思路: > 先用DFS將從根部到終端的所有路徑羅列出來,每條路徑都作為一個list, > 在這些路徑的list中找長度最長的,即為到達最深葉子的路徑,然後再從list末尾去找所有最長list的共同元素,即最低共同祖先 > 最後再次歷遍原本的二元樹,在最低共同祖先出現的時候,將預先令好的一個TreeNode的指標指向這位祖先,最後返回TreeNode的指標</font> ```python= class Solution: def lcaDeepestLeaves(self, root:Optional[TreeNode])->Optional[TreeNode]: dfs_ans = [] #放dfs的結果 def dfs(node,path): path.append(node.val) if not node.left and not node.right: dfs_ans.append(list(path)) #一定要list,否則加入的path是指標,會繼續被改變 return if node.left: dfs(node.left, list(path)) if node.right: dfs(node.right, list(path)) return dfs(root, []) #print(dfs_ans) longest=0 for i in dfs_ans: if len(i)>longest: longest=len(i) ans=[] for i in dfs_ans: if len(i)==longest: ans.append(i) #print(ans) if len(ans)==1: tree=TreeNode(ans[0][-1]) return tree def find(A): for i in range(len(A[0])-1,-1,-1): x=A[0][i] for j in range(1,len(A)): if x==ans[j][i]: if j==len(A)-1: #找到共同點 return ans[0][i] found=find(ans) #print(found) tree=TreeNode() def cut(node,x,tree): if not node: return None #print(node.val) if node.val==x: tree.left=node cut(node.left,x,tree) cut(node.right,x,tree) cut(root,found,tree) return tree.left ``` ![](https://hackmd.io/_uploads/SkwElR8S2.png) 花3小時,參考DFS的程式: [BFS vs DFS for Binary Tree - GeeksforGeeks](https://www.geeksforgeeks.org/bfs-vs-dfs-binary-tree/) [python || simple solution || recursive dfs](https://leetcode.com/problems/binary-tree-paths/solutions/2840036/python-simple-solution-recursive-dfs/) ## 心得 第三題的Channel Routing Problem,可能因為做法比較繁複,寫得很混亂,寫出來後再檢查、回顧時,發現好像{3,1} → {8,2} → {5} → {4,6}也符合最少track的安排方式?