題目描述如下:
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree [1,2,2,3,4,4,3] is symmetric:
1
/ \
2 2
/ \ / \
3 4 4 3
But the following [1,2,2,null,3,null,3] is not:
1
/ \
2 2
\ \
3 3
Note:
Bonus points if you could solve it both recursively and iteratively.
個人思路:
注意到題目描述最後提到,使用迭代和遞歸的方法會有加分,那麼我就決定使用遞歸來做這個題。首先思考這個題,判斷一個二叉樹是否爲鏡像,首先要結構上鏡像,其次要數據上鏡像,只要有一處不符合即可對此進行否定。這個時候我又想到了二叉樹的遍歷相關知識,我們比較常用的有先序遍歷NLR,中序遍歷LNR以及後續遍歷LRN。
經過觀察除去根節點之後的兩個符合鏡像要求的二叉樹(後面我們分別稱爲1、2)之後,我們發現,當我們沿着1的左孩子節點向下遍歷時,與我們沿着2的右孩子節點向下遍歷所得到的新的子樹仍舊滿足鏡像對稱。反過來,如果我們沿着1的右孩子節點向下遍歷時,與我們沿着2的左孩子節點向下遍歷所得到的新的子樹同樣滿足鏡像對稱。
通過上面的發現,我們可以開始着手解決問題了。對於兩顆鏡像對稱的二叉樹,我們可以通過改寫遞歸遍歷算法來對其進行判斷是否合法。對於根節點的左子樹,我們選擇LNR的中序遍歷,但是對於根節點的右子樹,我們選擇RNL的中序遍歷來實現。只要在遍歷時有一處出現不合法,即可中止遍歷,返回false。
代碼:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
bool check(TreeNode* node1,TreeNode* node2){ //改寫的遍歷算法,同時可以遍歷兩棵樹
if(!node1 && !node2) return true; //兩個皆NULL符合直接返回true
else if(!node1 || !node2) return false; //一個NULL一個非NULL,結構上失衡,返回false
if(check(node1->left,node2->right)){ //左子樹選擇LNR遍歷,右子樹選擇RNL遍歷
if(node1->val != node2->val) return false; //結構合法的前提下判斷數據是否合法
else return check(node1->right,node2->left);
}
else return false;
}
bool isSymmetric(TreeNode* root) {
if(!root) return true; //空樹
else return check(root->left,root->right);//樹非空,將樹分左右兩個子樹去遍歷
}