【劍指Offer】面試題18:樹的子結構

思路整理自劍指Offer

一:題目描述

輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)


二:解題思路

要查找樹A中找到和樹B結構一樣的子樹:

第一步:在樹A中找到和B的根節點的值一樣的結點R

第二步:判斷樹A中以R爲根節點的子樹是不是包含樹B一樣的結構


以一個例子進行說明:

1.我們在樹A中找到值爲8的結點:從A的根節點開始遍歷,我們發現它的根節點的值就是8

2.接着我們就去判斷樹A的根節點下面的子樹是否含有和樹B一樣的結構。

3.在樹A中,根節點的左子樹的值是8,而樹B的根節點的左子樹結點是9,對應的兩個結點不同。

4.因此我們仍然要遍歷樹A,接着查找的值爲8的結點,我們在樹的第二層找到一個值爲8的結點

5.判斷該結點下面的子樹是否含有和B樹一樣結構的子樹,先後找到兩個結點9,2,這和樹B的結構完全相同。因此樹B是樹A的子結構

以一個例子說明:

三:代碼實現

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    
    bool DoesTree1HaveTree2(TreeNode* pRoot1, TreeNode* pRoot2){
       //樹B遍歷完,則說明樹B是以pRoot爲根節點的子樹,是A的子樹
        if(pRoot2==NULL)
            return true;
        //如果B還沒有遍歷結束,pRoot1就已經遍歷完,則B不是子樹
        if(pRoot1==NULL)
            return false;
        
        //如果對應結點不相等,則B不是子樹
        if(pRoot1->val!=pRoot2->val)
            return false;
        
        //如果當前對應結點符合條件,則分別遍歷左子結點和右子節點
        return DoesTree1HaveTree2(pRoot1->left,pRoot2->left) && DoesTree1HaveTree2(pRoot1->right,pRoot2->right);
    }
    
    bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
    {
		bool result=false;
        
        //在每一處需要訪問地址的時候都要問自己這個地址有沒有可能是NULL,如果是NULL,如何處理
        if(pRoot1==NULL || pRoot2==NULL)
            return result;
        
        //如果A的R節點與B的根節點相同,那麼我們要判斷A中以R結點爲根節點的子樹是否包含和樹B一樣的結構
        if(pRoot1->val==pRoot2->val)
            result=DoesTree1HaveTree2(pRoot1,pRoot2);
        //如果R爲根節點的子樹不包含B,則繼續遍歷A,尋找與B樹根節點相同的結點
        //左子結點
        if(!result)
            result=HasSubtree(pRoot1->left,pRoot2);
        //右子節點
        if(!result)
            result=HasSubtree(pRoot1->right,pRoot2);
        
        return result;
    }
};

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章