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 scould 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.
這道題讓我們求一個數是否是另一個樹的子樹,從題目中的第二個例子中可以看出,子樹必須是從葉結點開始的,中間某個部分的不能算是子樹,那么我們轉換一下思路,是不是從s的某個結點開始,跟t的所有結構都一樣,那么問題就轉換成了判斷兩棵樹是否相同,也就是Same Tree的問題了,這點想通了其實代碼就很好寫了,用遞歸來寫十分的簡潔,我們先從s的根結點開始,跟t比較,如果兩棵樹完全相同,那么返回true,否則就分別對s的左子結點和右子結點調用遞歸再次來判斷是否相同,只要有一個返回true了,就表示可以找得到。
解法一:
class Solution { public: bool isSubtree(TreeNode* s, TreeNode* t) { if (!s) return false; if (isSame(s, t)) return true; return isSubtree(s->left, t) || isSubtree(s->right, t); } bool isSame(TreeNode* s, TreeNode* t) { if (!s && !t) return true; if (!s || !t) return false; if (s->val != t->val) return false; return isSame(s->left, t->left) && isSame(s->right, t->right); } };
下面這道題的解法用到了之前那道Serialize and Deserialize Binary Tree的解法,思路是對s和t兩棵樹分別進行序列化,各生成一個字符串,如果t的字符串是s的子串的話,就說明t是s的子樹,但是需要注意的是,為了避免出現[12], [2], 這種情況,雖然2也是12的子串,但是[2]卻不是[12]的子樹,所以我們再序列化的時候要特殊處理一下,就是在每個結點值前面都加上一個字符,比如',',來分隔開,那么[12]序列化后就是",12,#",而[2]序列化之后就是",2,#",這樣就可以完美的解決之前的問題了,參見代碼如下:
解法二:
class Solution { public: bool isSubtree(TreeNode* s, TreeNode* t) { ostringstream os1, os2; serialize(s, os1); serialize(t, os2); return os1.str().find(os2.str()) != string::npos; } void serialize(TreeNode* node, ostringstream& os) { if (!node) os << ",#"; else { os << "," << node->val; serialize(node->left, os); serialize(node->right, os); } } };
類似題目:
Serialize and Deserialize Binary Tree
參考資料:
https://discuss.leetcode.com/topic/88508/java-solution-tree-traversal
https://discuss.leetcode.com/topic/88491/java-concise-o-n-m-time-o-n-m-space
https://discuss.leetcode.com/topic/88700/easy-o-n-java-solution-using-inorder-and-preorder-traversal