1. 程式人生 > >【LeetCode】101. Symmetric Tree 中序遍歷,分支遍歷,二叉樹

【LeetCode】101. Symmetric Tree 中序遍歷,分支遍歷,二叉樹

101. Symmetric Tree

Total Accepted: 103742Total Submissions: 306773Difficulty: Easy

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree is symmetric:

    1
   / \
  2   2
 / \ / \
3  4 4  3

But the following is not:

    1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.

【分析】

     這個題比較簡單,觀察對稱二叉樹的結構,很容易發現其中序遍歷具有對稱性,如題中給出的例子:[1,2,2,3,4,4,3],其中序遍歷為:[3,2,4,1,4,2,3]。幾分鐘隨手寫好程式,然而在192個測試用例測試中,在第190個測試時輸出了錯誤結果,費解之餘看了一下那個案例:[1,2,3,3,NULL,2,3,NULL],中序遍歷不能記錄NULL,所以這個案例的中序遍歷結果為[3,2,1,2,3],居然也對稱,但它並不是

對稱二叉樹鑑於此,僅僅憑藉中序遍歷結果判斷是否為對稱二叉樹是不嚴謹的!!!

     為了規避上面的問題,我們只需在驗證中序遍歷結果的基礎上增加一個判斷,那就是驗證根節點的左右子節點數值是否相等(前提是左右子節點不為空),如果相等且中序遍歷結果對稱則必為對稱樹。這種方法時間複雜度為O(n),空間複雜度為O(n).

     受上述判斷的啟發,我們可進一步降低時間、空間複雜度:根據對稱樹具備的對稱性,我們逐層遍歷,分別比較根節點的左右子節點是否對稱,注意:對於左、右子樹,左子樹根節點的左子節點對應右子樹根節點的右子節點;左子樹的根節點的右子節點對應右子樹根節點的左子節點。此方法程式簡潔,時間複雜度O(n)

,比方法一計算次數要少,空間複雜度為O(1),不消耗額外空間,是比較理想的解法。

【方法一】

class Solution {
public:
    bool isSymmetric(TreeNode* root) 
    {
        vector<int> res;//儲存中序遍歷結果
        if(root==NULL)return true;
        inorderTraversal(root,res);//中序遍歷
        //判斷中序遍歷結果是否對稱
        for(int i=0;i<res.size();i++)
        {
            if(res[i]!=res[res.size()-i-1])
            return false;
        }
        //驗證根節點左右子節點是否對稱
        if(root->left!=NULL&&root->left!=NULL&&root->left->val!=root->right->val)
        return false;
        return true;
    }
    //中序遍歷
    void inorderTraversal(TreeNode *root,vector<int>& res)
    {
        if(root==NULL)return;
        inorderTraversal(root->left, res);
        res.push_back(root->val);
        inorderTraversal(root->right, res);
    }
};
【方法二】
class Solution {
public:
    bool isSymmetric(TreeNode* root) 
    {
        if(root==NULL)return true;
        return checkSymmetric(root->left,root->right);
    }
    bool checkSymmetric(TreeNode *leftNode,TreeNode *rightNode)
    {
        if(leftNode==NULL&&rightNode==NULL)return true;
        if(leftNode==NULL||rightNode==NULL)
        return false;
        if(leftNode->val!=rightNode->val)
        return false;
        
        return checkSymmetric(leftNode->left,rightNode->right)&&checkSymmetric(leftNode->right,rightNode->left);
    }
};