---
# System prepended metadata

title: '**Leetcode筆記(Subtree of Another Tree)**'
tags: [medium, binary tree, leetcode]

---

# **Leetcode筆記(Subtree of Another Tree)**


:::info
:information_source: 題目 : Subtree of Another Tree, 類型 : binary tree , 等級 : easy
日期 : 2023/03/19，2023/05/25，2023/07/05，2025/03/05
:::


### 嘗試

```python
class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        if not root or not subRoot:
            return False
        
        node = self.findStart(root, subRoot)
        self.sameTree(node, subRoot)
        
    def sameTree(self, a, b):
        if not a and not b:
            return True
        if not a or b: # 大樹null
            return False
        if a or not b: # 小樹null
            return True
        if a.val != b.val:
            return False
        return (self.sameTree(a.left, a.right)) and (self.sameTree(b.left, b.right))


    def findStart(self, root, subRoot):
        if root.val == subRoot.val:
            return root
        else:
            self.findStart(root.left, subRoot)
            self.findStart(root.right, subRoot)
```
2023/05/25
```python
class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        
        if not subRoot:
            return True
        if not root:
            return False

        def sameTree(node1, node2):
            if not node1 and not node2:
                return True
            if not node1 or not node2:
                return False
            if node1.val != node2.val:
                return False
            return (sameTree(node1.left, node2.left) and sameTree(node1.right, node2.right))

        def bfs(root, subRoot):
            # 已經窮盡到底部
            if not root:
                return False
            if sameTree(root, subRoot):
                return True
            # 記得subRoot不用變  
            # 記得這邊要回傳合格訊息 任一True即可
            return (bfs(root.right, subRoot) or bfs(root.left, subRoot))
        
        return bfs(root, subRoot)
```
2023/07/05
在主函式中，會先檢查root是不是和subRoot相同的，如果不是的話就往下呼叫主函式isSubtree(root.left, subRoot)和self.isSubtree(root.right, subRoot)，這個函式就會慢慢把全部的都遍歷完，有其中一次遞迴回傳True的話，因為是or判斷式，所以都會回傳True

```python
class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        if not root:
            return False
        if not subRoot:
            return True

        if self.isSameTree(root, subRoot):
            return True
        else:
            l = self.isSubtree(root.left, subRoot)
            r = self.isSubtree(root.right, subRoot)
            return l or r # 只要有一層回傳True
            # 那總會往上傳到整個都是True


    def isSameTree(self, q, p):
        if not q and not p:
            return True
        if not q or not p:
            return False
        if q.val != p.val:
            return False
        
        return (self.isSameTree(q.left, p.left) and self.isSameTree(q.right, p.right))
```

2025/03/05
主函式檢查是否為相同樹，如果不是，則遞迴檢查其左右樹，以左樹或右樹為root。isSubtree的self.sameTree呼叫，可以想像是base case，只要有一為True，則回傳True
```python
class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        if not root:
            return False
        if self.sameTree(root, subRoot):
            return True

        return self.isSubtree(root.left, subRoot) or self.isSubtree(root.right, subRoot)

    def sameTree(self, node1, node2):
        if not node1 and not node2:
            return True
        elif not node1 or not node2:
            return False
        elif node1.val != node2.val:
            return False
        
        return self.sameTree(node1.left, node2.left) and self.sameTree(node1.right, node2.right)
```

---
### **優化**

原本不太懂為什麼還要呼叫一次isSubtree，最後得出可能跟root是誰有關，如果不重新呼叫的話，root永遠是從最上面開始
時間複雜度O(s*t)，時間複雜度是考慮最差的情況發生，即每個s和t都要跑一整遍
```python
class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        if not root: # 大樹null
            return False
        if not subRoot: # 小樹null
            return True
        
        if self.sameTree(root, subRoot):
            # 若讓sametree一直跑 結果為true
            # self.sameTree(root, subRoot)回傳bool
            return True
        else:
            # 更換root
            return ( self.isSubtree(root.right, subRoot) or self.isSubtree(root.left, subRoot) )
        
    def sameTree(self, a, b):
        if not a and not b: # 最後都是null
            return True
        if not a or not b:
            return False
        if a.val != b.val:
            return False
        # 跑到這 val相同且ab皆不為null

        return (self.sameTree(a.left, b.left) and self.sameTree(a.right, b.right))
```
比較像自己原本的寫法的優化
```python
class Solution:
    def isSubtree(self, root: Optional[TreeNode], subRoot: Optional[TreeNode]) -> bool:
        
        if self.subtree(root, subRoot):
            return True
        else:
            return False
        
    def sameTree(self, a, b):
        if not a and not b: # 最後都是null
            return True
        if not a or not b:
            return False
        if a.val != b.val:
            return False
        # 跑到這 val相同且ab皆不為null

        return (self.sameTree(a.left, b.left) and self.sameTree(a.right, b.right))
    
    def subtree(self, root, subRoot):
        if not root: # 大樹null
            return False
        if not subRoot: # 小樹null
            return True

        if self.sameTree(root, subRoot):
            # 若讓sametree一直跑 結果為true
            # self.sameTree(root, subRoot)回傳bool
            return True
        else:
            # 更換root
            return ( self.subtree(root.right, subRoot) or self.subtree(root.left, subRoot) )
```
---


**:warning: 錯誤語法** 
:::warning
如果要創一個function，位置是和原function平行，並且要記得加self，def sameTree(self, a, b)
呼叫自己的時候也要記得加self
若在return東西的時候，若順便呼叫自己，要把東西用括號括起來，可以想成return只能傳一個bool
:::


**:thumbsup:學習** 
:::success
subtree : 包含全部該點下面的node
:::

**思路**


**講解連結**
https://www.youtube.com/watch?v=E36O5SWp-LE
https://www.youtube.com/watch?v=wDsFfgv4OGY
![](https://hackmd.io/_uploads/SkWNDPzFn.png)

Provided by. NeetCode & nETSETOS(很好的講解遞迴)

###### tags: `binary tree` `medium` `leetcode`