题目要求:给你一个二叉树的根节点 root
, 检查它是否轴对称。
例如:
输入:root = [1,2,2,3,4,4,3]
输出:true
解题思路:
【一种错误的想法】
有一种方法是把二叉树顺序遍历一遍,再逆序遍历一遍,有什么方法能体现遍历是父节点、左子树、右子树的顺序呢?
——答案是中序遍历,中序遍历会访问先左子树 再父节点 后右子树。
于是,是不是可以先顺序中序遍历一遍,在逆序地中序遍历一遍(就是遍历的时候先访问右子树再访问左子树),然后比较两种遍历对应元素的值是否一样。这样顺序中序遍历的结果是[3, 2, 4, 1, 4, 2, 3],逆序遍历的结果是[3, 2, 4, 1, 4, 2, 3],一对比,结果一样,于是判断对称。
——但是,这个方法其实不行!
反例:
这样的话,循序终须中序遍历和逆序中序遍历的结果都是[2, 2, 1, 2, 2]
这种方法的错误之处在于只是用数值来比较对称性,没有用到位置信息(中序遍历体现了顺序信息,而没有很好地体现位置信息,所以还是不行)。
【正确的想法】
递归地判断二叉树对称位置上的元素是不是相等。
思路:对于每个节点,判断是否对称,就是比较左子树的右子树和右子树的左子树是否对称、左子树的左子树和右子树的右子树是否对称。
即
bool compare(TreeNode* left_root, TreeNode* right_root){
return compare(left_root->left, right_root->right) && compare(left_root->right, right_root->left);
}
当然,还有递归结束条件:
(1)左子树和右子树为空,说明对称,返回true
(2)左子树或右子树为空,说明不对称,返回false
(3)左子树和右子树都不是空的,比较数值,如果数值相等,继续递归,如果数值不相等,说明不对称,返回false。
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool compare(TreeNode* left_root, TreeNode* right_root){
if(left_root==nullptr && right_root == nullptr) return true;
if(left_root==nullptr || right_root == nullptr) return false;
if(left_root->val != right_root->val) return false;
return compare(left_root->left, right_root->right) && compare(left_root->right, right_root->left);
}
bool isSymmetric(TreeNode* root) {
if(root == nullptr) return true;
return compare(root->left, root->right);
}
};
时间复杂度分析:遍历了整棵树(或者说是遍历了整棵树的半边,另外半边是同步遍历的),时间复杂度为O(N);空间复杂度:最坏的情况是二叉树退化为链表,栈的深度为N(准确的说是),复杂度为O(N)。
有什么问题欢迎与我交流~