LeetCode572. Subtree of Another Tree (另一個棵樹的子樹)
原題
Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node’s descendants. The tree s could also be considered as a subtree of itself.
Example 1:
Given tree s:
3
/ \
4 5
/ \
1 2
Given tree t:
4
/ \
1 2
Return true, because t has the same structure and node values with a subtree of s.
Example 2:
Given tree s:
3
/ \
4 5
/ \
1 2
/
0
Given tree t:
4
/ \
1 2
Return false.
Reference Answer
Method one: DFS + DFS
容易想到,要判斷一個樹是不是另外一個樹的子樹,那麼可以通過判斷和這個數的任意子樹是否相等的方式來做。那麼就和100. Same Tree挺像了。所以這個題的做法就是在判斷兩棵樹是否相等的基礎上,新增上任意子樹是否相等的判斷。
任意子樹是否相等判斷的方式是:
- 當前兩棵樹是否相等
- s的左孩子和t是否相等
- t的左孩子和t是否相等
這三個條件是 或 的關係。
注意,判斷兩個數是否相等是與的關係。
判斷是否是子樹與是否是相同的樹的程式碼簡直是對稱美啊~
這裡很值得注意的一個地方時,無論是方法一還是方法二,都用瞭如下程式碼先從樹結構進行判定:
if not s and not t:
return True
if not s or not t:
return False
其依據是“在當節點為空的時候給一個“#”表示,這樣就能表示出不同的子樹,因此只需要遍歷一次就能得到結果。每次遍歷到樹的結尾的時候能夠按照#區分,另外每個樹的節點值之間用","分割。”
Code
class Solution:
def isSubtree(self, s, t):
"""
:type s: TreeNode
:type t: TreeNode
:rtype: bool
"""
# 1. method one: DFS + DFS
if not s and not t:
return True
if not s or not t:
return False
return self.isSameTree(s,t) or self.isSubtree(s.left, t) or self.isSubtree(s.right, t)
def isSameTree(self, s, t):
if not s and not t:
return True
if not s or not t:
return False
return s.val == t.val and self.isSameTree(s.left, t.left) and self.isSameTree(s.right, t.right)
Method Two: BFS + DFS
因為s的每個節點都可能成為和t相等的根節點,那麼我們使用BFS來遍歷每個節點,然後對每個節點進行判斷就好了。
參考答案採用了
colletions.deque()
暫存節點,這種方式比採用list
更巧妙,先進先出也完全符合程式設定。
class Solution:
def isSubtree(self, s, t):
"""
:type s: TreeNode
:type t: TreeNode
:rtype: bool
"""
# 2. method two: BFS + DFS
if not s and not t:
return True
if not s or not t:
return False
que = collections.deque()
que.append(s)
while que:
node = que.popleft()
if not node:
continue
if self.isSameTree(node, t):
return True
que.append(node.left)
que.append(node.right)
return False
def isSameTree(self, s, t):
if not s and not t:
return True
if not s or not t:
return False
return s.val == t.val and self.isSameTree(s.left, t.left) and self.isSameTree(s.right, t.right)
Note
- 自己嘗試著用後續遍歷進行判定,儲存兩棵樹節點值,進行判定的依據是認為是子樹結構必然儲存在後續遍歷開始,沒通過的原因正是在於該依據有錯誤,當樹結構比較深時,其子結構可能存在中間,這時候子樹結構無法對應原樹結構的開始節點位置。
參考文獻
[1] https://blog.csdn.net/fuxuemingzhu/article/details/71440802