1. 程式人生 > >子樹(LintCode)

子樹(LintCode)

題目來源:LintCode

原題地址:http://www.lintcode.com/zh-cn/problem/subtree/#

題目:

有兩個不同大小的二進位制樹:T1有上百萬的節點;T2有好幾百的節點。請設計一種演算法,判定T2是否為T1的子樹。

您在真實的面試中是否遇到過這個題? Yes 樣例

下面的例子中 T2 是 T1 的子樹:

       1                3
      / \              / 
T1 = 2   3      T2 =  4
        /
       4

下面的例子中 T2 不是 T1 的子樹:

       1               3
      / \               \
T1 = 2   3       T2 =    4
        /
       4
注意

若 T1 中存在從節點 n 開始的子樹與 T2 相同,我們稱 T2 是 T1 的子樹。也就是說,如果在 T1 節點 n 處將樹砍斷,砍斷的部分將與 T2 完全相同。


難度級別:
容易
思路分析:
本題採用的策略其實很簡單,就是選擇一個常用的樹的遍歷方式,對每個節點進行遍歷操作;
對於每個節點都進行對比操作,看看是否從當前節點開始是否是子樹。
實現程式碼:
/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
class Solution
{
public:
	/**
	* @param T1, T2: The roots of binary tree.
	* @return: True if T2 is a subtree of T1, or false.
	*/
	bool isSubtree(TreeNode *T1, TreeNode *T2)
	{
		if (T1 == NULL && T2 == NULL)
		{
			return true;
		}else if (T1 == NULL && T2 != NULL)
		{
			return false;
		}
		if (isSubtreeCore(T1, T2))
		{
			return true;
		}
		if (isSubtree(T1->left, T2))
		{
			return true;
		}
		if (isSubtree(T1->right, T2))
		{
			return true;
		}
		return false;
	}
	bool isSubtreeCore(TreeNode *T1, TreeNode *T2)
	{
		if (T1 == NULL && T2 == NULL)
		{
			return true;
		}
		if (T1 == NULL || T2 == NULL)
		{
			return false;
		}
		if (T1->val != T2->val)
		{
			return false;
		} else
		{
			if (!isSubtreeCore(T1->left, T2->left))
			{
				return false;
			}
			if (!isSubtreeCore(T1->right, T2->right))
			{
				return false;
			}
		}
		return true;
	}

};


程式碼說明:
其實這個程式碼挺簡單的,需要說明的是:
我原先習慣如果下一個節點為空的話 就不進入了,不過此題的情況比較特殊,會有子樹為空的情況,所以不能這麼處理。
所以不管是否為空都要進入下一個節點。
或者 把空子樹這個情況單列出來進行處理,也是可以的。