---
# System prepended metadata

title: 演算法導論 HW10

---

# 演算法導論 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的安排方式?