题目如下:
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
题目分析:
这道题目的递归解答比较好想,看图写码即可。非递归解答我是花了不少时间才搞定,一开始还尝试着queue+stack的方式逐排扫描,还很激动自己想了个很简洁的办法,结果发现错了,连题目中提到反例都解决不掉。于是注意到不仅要数字大小的对称,而且要左右的对称,比如上面反例中的第三行3和3,数字对称但是左右不对称。于是重新改重新提交试了几次终于搞定。
我的递归版本代码如下
//递归版
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool testSymmetric(TreeNode* left, TreeNode* right) {
if(left==NULL&&right==NULL)
return true;
else if(left==NULL&&right!=NULL)
return false;
else if(left!=NULL&&right==NULL)
return false;
else if(left!=NULL&&right!=NULL&&left->val!=right->val)
return false;
else
return testSymmetric(left->left,right->right)&&testSymmetric(left->right,right->left);
}
bool isSymmetric(TreeNode *root) {
if (root==NULL)
return true;
else
return testSymmetric(root->left,root->right);
}
};
我的非递归版本如下:
//非递归版 44ms过大集合
class Solution {
public:
bool isSymmetric(TreeNode *root) {
stack<TreeNode*> node_stack;
vector<TreeNode*> node_vector;
queue< vector<TreeNode*> > large_node_queue;
if((root==NULL)||(root!=NULL&&root->left==NULL&&root->right==NULL))
return true;
if((root->left!=NULL&&root->right==NULL)||(root->left==NULL&&root->right!=NULL))
return false;
node_vector.push_back(root->left);
node_vector.push_back(root->right);
large_node_queue.push(node_vector);
while(!large_node_queue.empty()) {
node_vector=large_node_queue.front();
large_node_queue.pop();
vector<TreeNode*> node_vector2;
int i=0;
int j=(int)node_vector.size()-1;
while(i<j){
if( (node_vector[i]==NULL&&node_vector[j]!=NULL) || (node_vector[i]!=NULL&&node_vector[j]==NULL) )
return false;
if(node_vector[i]!=NULL&&node_vector[j]!=NULL&&node_vector[i]->val!=node_vector[j]->val)
return false;
i++;
j--;
}
for(i=0;i<(int)node_vector.size();i++){
if(node_vector[i]!=NULL){
node_vector2.push_back(node_vector[i]->left);
node_vector2.push_back(node_vector[i]->right);
}
}
if(!node_vector2.empty())
large_node_queue.push(node_vector2);
}
return true;
}
};
小结:
(1) 越来越发现,写代码的时间要想短,一定要想清楚了逻辑框架和边界条件再写。写完了还不要忘记去测测正例和反例。如果想依靠debug去把一个代码写好,那将是非常花时间的。这不仅仅是为了面试,也是为了提高工作效率。
update 2014-10-09 递归版改得更简洁了
class Solution {
private:
bool mySymmetric(TreeNode* left_node, TreeNode* right_node) {
if (left_node != NULL && right_node != NULL && left_node->val == right_node->val)
return mySymmetric(left_node->left, right_node->right) &&
mySymmetric(left_node->right, right_node->left);
else if (left_node == NULL && right_node == NULL)
return true;
else
return false;
}
public:
bool isSymmetric(TreeNode *root) {
if (root == NULL) return true;
return mySymmetric(root->left, root->right);
}
};
update 2014-10-09 非递归版也改的更简洁了
class Solution {
public:
bool isSymmetric(TreeNode *root) {
vector<TreeNode*> node_vector;
if (root == NULL)
return true;
node_vector.push_back(root->left);
node_vector.push_back(root->right);
while (!node_vector.empty()) {
vector<TreeNode*> node_vector_tmp;
int i=0;
int j=(int)node_vector.size() - 1;
while (i < j) {
if( (node_vector[i] == NULL && node_vector[j] != NULL) || (node_vector[i] != NULL && node_vector[j] == NULL) )
return false;
if(node_vector[i] != NULL && node_vector[j] != NULL && node_vector[i]->val != node_vector[j]->val)
return false;
++i;
--j;
}
for (i = 0; i < (int)node_vector.size(); ++i){
if(node_vector[i]!=NULL){
node_vector_tmp.push_back(node_vector[i]->left);
node_vector_tmp.push_back(node_vector[i]->right);
}
}
node_vector.swap(node_vector_tmp);
}
return true;
}
};