对称的二叉树
- 参与人数:1963时间限制:1秒空间限制:32768K
- 算法知识视频讲解
题目描述
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
考虑测试用例:
上代码:
// 53.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
using namespace::std;
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
class Solution {
public:
bool isSymmetrical(TreeNode* pRoot) {
if (pRoot == NULL) return true;
vector<int> leftVec;
vector<int> rightVec;
travLeft(pRoot, leftVec);
travRight(pRoot, rightVec);
if (leftVec.size() != rightVec.size()) return false;
bool retVal = true;
for (int i = 0; i < leftVec.size(); i++) {
if (leftVec[i] != rightVec[i]) {
retVal = false;
break;
}
}
return retVal;
}
void travLeft(TreeNode* pNode, vector<int>& leftVec) {
//if (pNode == NULL) {
// leftVec.push_back(-1);
// return;
//}
leftVec.push_back(pNode->val);
if (pNode->left)
travLeft(pNode->left, leftVec);
else{
leftVec.push_back(-1);
return;
}
if (pNode->right)
travLeft(pNode->right, leftVec);
else{
leftVec.push_back(-1);
return;
}
}
void travRight(TreeNode* pNode, vector<int>& rightVec) {
//if (pNode == NULL) {
// rightVec.push_back(-1);
// return;
//}
rightVec.push_back(pNode->val);
if (pNode->right)
travRight(pNode->right, rightVec);
else{
rightVec.push_back(-1);
return;
}
if (pNode->left)
travRight(pNode->left, rightVec);
else{
rightVec.push_back(-1);
return;
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
TreeNode p1(5);
TreeNode p2(5);
TreeNode p3(5);
TreeNode p4(5);
TreeNode p5(5);
TreeNode p6(5);
p1.left = &p2;
p1.right = &p3;
p2.left = &p4;
p2.right = &p5;
p3.left = &p6;
Solution s;
bool result = s.isSymmetrical(&p1);
return 0;
}
思路:
1.对二叉树做前序遍历,把前序遍历的结果装入leftVec中,注意,一般遍历到叶节就返回了,但是这里我们要再进一步,遍历到叶节点的下一位,叶节点的下一位为NULL,如果节点为NULL,就把-1压入leftVec;
2.对二叉树做前序遍历的对称遍历,即先遍历根节点,然后遍历左子节点,再遍历右子节点,把对称遍历的结果装入rightVec ,注意,一般遍历到叶节就返回了,但是这里我们要再进一步,遍历到叶节点的下一位,叶节点的下一位为NULL,如果节点为NULL,就把-1压入rightVec;3.如果leftVec和rightVec的长度不同,必然退出二叉树不对称,直接返回false;4.依次对比leftVec和rightVec每个元素值,如果全部相同,说明二叉树对称,否则二叉树不对称;
travLeft()函数对二叉树做前序遍历,并把前序遍历的结果存入leftVec,先构建二叉树前序遍历的框架:
void travLeft(TreeNode* pNode, vector<int>& leftVec) {
leftVec.push_back(pNode->val);
if (pNode->left).............
if (pNode->right)............
}
再丰富框架:
void travLeft(TreeNode* pNode, vector<int>& leftVec) {
leftVec.push_back(pNode->val);
if (pNode->left)
travLeft(pNode->left, leftVec);
else{
leftVec.push_back(-1); // 我们要遍历到叶子节点的下一位
return;
}
if (pNode->right)
travLeft(pNode->right, leftVec);
else{
leftVec.push_back(-1); // 我们要遍历到叶子节点的下一位
return;
}
}
travRight()函数对二叉树做对称前序遍历,并把对称前序遍历的结果存入rightVec,先构建二叉树对称前序遍历的框架:
void travRight(TreeNode* pNode, vector<int>& rightVec) {
rightVec.push_back(pNode->val);
if (pNode->right)....
if (pNode->left).......
}
再丰富框架:
void travRight(TreeNode* pNode, vector<int>& rightVec) {
rightVec.push_back(pNode->val);
if (pNode->right)
travRight(pNode->right, rightVec);
else{
rightVec.push_back(-1);// 我们要遍历到叶子节点的下一位
return;
}
if (pNode->left)
travRight(pNode->left, rightVec);
else{
rightVec.push_back(-1); // 我们要遍历到叶子节点的下一位
return;
}
}
第二次做,之前看过一个源码,里面提倡一种理念:函数只有一个出口,第二次做我就采用了这种理念,使用 goto 语句跳转~
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
bool isSymmetrical(TreeNode* pRoot) {
if ( pRoot == NULL ) return true ;
bool rc = false ;
vector<int> leftVec ;
vector<int> rightVec ;
startLeft( leftVec, pRoot ) ;
startRight( rightVec, pRoot ) ;
if ( leftVec.size() != rightVec.size() ) {
goto done ;
}
for ( int i = 0; i < leftVec.size(); ++ i ) {
if ( leftVec[i] != rightVec[i] ) {
goto done ;
}
}
rc = true ;
error :
goto done ;
done :
return rc ;
}
void startLeft( vector<int>& leftVec, TreeNode* pNode ) {
leftVec.push_back( pNode->val ) ;
if ( pNode->left != NULL ) {
startLeft( leftVec, pNode->left ) ;
} else {
leftVec.push_back( -1 ) ;
return ;
}
if ( pNode->right != NULL ) {
startLeft( leftVec, pNode->right ) ;
} else {
leftVec.push_back( -1 ) ;
return ;
}
}
void startRight( vector<int>& rightVec, TreeNode* pNode ) {
rightVec.push_back( pNode->val ) ;
if ( pNode->right != NULL ) {
startRight( rightVec, pNode->right ) ;
} else {
rightVec.push_back( -1 ) ;
return ;
}
if ( pNode->left != NULL ) {
startRight( rightVec, pNode->left ) ;
} else {
rightVec.push_back( -1 ) ;
return ;
}
}
};
第三次做,一杆过~
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
bool isSymmetrical(TreeNode* pRoot) {
if ( pRoot == NULL ) return true ;
vector<int> vec_left ;
vector<int> vec_right ;
trav_left( pRoot, vec_left ) ;
trav_right( pRoot, vec_right ) ;
if ( vec_left.size() != vec_right.size() ) return false ;
for ( int i = 0; i < vec_left.size(); ++ i ) {
if ( vec_left[i] != vec_right[i] ) return false ;
}
return true ;
}
void trav_left( TreeNode* node, vector<int>& vec_left ) {
vec_left.push_back( node->val ) ;
if ( node->left ) trav_left( node->left, vec_left ) ;
else {
vec_left.push_back( -1 ) ;
return ;
}
if ( node->right ) trav_left( node->right, vec_left ) ;
else {
vec_left.push_back( -1 ) ;
return ;
}
}
void trav_right( TreeNode* node, vector<int>& vec_right ) {
vec_right.push_back( node->val ) ;
if ( node->right ) trav_right( node->right, vec_right ) ;
else {
vec_right.push_back( -1 ) ;
return ;
}
if ( node->left ) trav_right( node->left, vec_right ) ;
else {
vec_right.push_back( -1 ) ;
return ;
}
}
};