題目
對稱二叉樹
二叉樹由于其本身具有遞歸特性,所以絕大部分二叉樹的算法題用遞歸的方法都很好解。如果不用遞歸方法,也可以使用堆棧以及隊列來對二叉樹進行迭代,其實算法思想都是一樣的。
這道題有兩個解題思路:
第一個思路是層序遍歷,因為對稱二叉樹每一層的遍歷結果都是回文串。這樣的方法雖然比較直觀,但是實現起來不如下面的簡單。
第二個思路是,在對稱二叉樹中,我們把整棵樹分為左部分和右部分(根節點的左右子樹),其中左部分和右部分是鏡像對稱的,所以有這樣的結論:左子樹的左子樹和右子樹的右子樹的節點值是相等的(這里指的是左子樹的左子樹的根節點,而不是整顆子樹),且左子樹的右子樹和右子樹的左子樹也有這樣的結論。
對稱二叉樹中相等的部分
下面是分別用遞歸和迭代的方法來解題,算法思路是一樣的:
1.遞歸
class Solution {
public:
bool compareTree(TreeNode* left, TreeNode* right) {
if (left == NULL && right == NULL) return true;
else if (left == NULL && right != NULL || left != NULL && right == NULL) return false;
if (left->val == right->val) {
return compareTree(left->left, right->right) && compareTree(left->right, right->left);
} else {
return false;
}
}
bool isSymmetric(TreeNode* root) {
if (root == NULL) return true;
return compareTree(root->left, root->right);
}
};
2.迭代
class Solution {
public:
bool isSymmetric(TreeNode* root) {
if(!root) return true;
stack<TreeNode*> s;
if(root->left and root->right){
s.push(root->left);
s.push(root->right);
} else if(!root->left and !root->right) {
return true;
} else {
return false;
}
while(!s.empty()){
TreeNode* p = s.top();
s.pop();
TreeNode* q = s.top();
s.pop();
if(p->val != q->val) return false;
if(p->left and q->right){
s.push(p->left);
s.push(q->right);
} else if((p->left and !q->right) or (!p->left and q->right)) {
return false;
}
if(p->right and q->left){
s.push(p->right);
s.push(q->left);
} else if((p->right and !q->left) or (!p->right and q->left)) {
return false;
}
}
return true;
}
};