【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)
【方法一】
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);
}
};