1. 題目描述
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
2. 樣例
For example, this binary tree [1,2,2,3,4,4,3] is symmetric:
But the following [1,2,2,null,3,null,3] is not:
3. 分析
題目的意思是:給了一個二叉樹的根節點,讓我們判斷這棵樹是否是對稱的,對稱的意思是關於它的中心左右對稱。
很明顯,根據我的分析:樹的對稱是有兩個條件的:
- 對應層次,左右節點的結構是對稱的,即這一層左右節點數目是對稱的:而且該層左面有N,M個左右孩子,右面就需要有對應的N,M個右左孩子。如上文的第一個例子是符合的,而上文第二個例子就是因爲第二層左邊有一個右孩子,而右邊有一個右孩子,所以不對稱。
- 對應節點數值:每一層只有結構對稱還是不夠,對應節點的數值也必須相同。
分析之後,我原來的想法是:利用層次遍歷,遍歷樹的每一層,用一個棧stack來進行不斷入棧出棧操作,從而進行匹配。但是這個思路被否決了,因爲這個只能滿足第二個數值匹配的要求,而無法滿足結構對稱的要求,例子2就可以進行反駁。
因此,我設計的算法是利用遞歸,分而治之:從根節點開始,不斷判斷每一層對應兩個位置的節點情況,所謂的對應位置就是在該層成對稱位置分佈的節點:
- 如果一個爲NULL,一個不爲NULL:說明該層結構不對稱,即不滿足要求1,直接false
- 如果均爲NULL,則true
- 如果均不爲NULL,則判斷節點存儲數值:如果不同,則不滿足要求2,直接false;如果相同,則繼續查找該兩個節點下的左右和右左孩子
如下圖所示:
提交後,結果如下:
4. 源碼
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool comTwoNode(TreeNode*leftNode, TreeNode*rightNode) {
if (leftNode != NULL && rightNode != NULL) {
if (leftNode->val != rightNode->val) {
return false;
}
}
else if (leftNode != NULL || rightNode != NULL) {
return false;
}
else {
return true;
}
return comTwoNode(leftNode->left, rightNode->right)&&comTwoNode(leftNode->right, rightNode->left);
}
bool isSymmetric(TreeNode* root) {
if (root == NULL) {
return true;
}
return comTwoNode(root->left, root->right);
}
};
5. 心得
最近做BFS的題,一上來的思路就被非遞歸的層次遍歷限制住了,稍加思考就能得到遞歸的清晰簡單的算法。