代码随想录刷题Day34
翻转二叉树
递归思路抽象出这个翻转的过程:先是对左右子树翻转,接着再交换左右孩子节点的位置:
class Solution {
public:TreeNode* invertTree(TreeNode* root) {if(!root) return root;else{invertTree(root->left);invertTree(root->right);TreeNode* tmp = root->left;root ->left = root -> right;root->right = tmp;return root;}}
};
对称二叉树
这个题目花了比较多时间思考和写,想过几种方案,都没能写出来,最后还得再看代码随想录的标准答案,才恍然大悟,原来也可以用递归的思路来解决。
首先,我自己最开始的思路,是基于上一题的翻转二叉树,我想的是,对要判断是否对称的二叉树root来一个翻转操作得到一棵新树root_invert,接着比较root和invert_root时候一致,如果一致,说明root本身就是对称的,否者说明root不是对称的。但是代码思想这个思路之后,在比较两棵树的时候,一直有bug出现,应该是细节不太对,卡了比较久,还是放弃了这条思路。
接着是粗略参考代码随想录的标准答案,看到可以用后序遍历+递归的思路,于是我还没想清楚就直接写代码,写代码是对左子树进行左右中的后序遍历,对右子树进行右左中的后序遍历,然后对得到的左子树的遍历序列和右子树的遍历序列进行比较,如果不一致则说明不是对称的,但是这样的做法,显然是没有考虑到题目给出的第二个样例的情况。对于分别只有一个孩子的左右子树,如果左子树存在的是右孩子,右子树存在的也是右孩子,如果值还一样,这在这样的思路下会得出这对节点是对称的误判结果。
最后,还是得认真参考官方题解,定义一个比较函数,用于比较左右两棵子树是否对称,具体的比较过程,先是左右子树根节点是否一致,接着是对子树的外侧和内侧接节点的比较,如此迭代下去。
class Solution {
public:bool compare(TreeNode* left,TreeNode* right){//比较左右孩子节点if(left == nullptr && right!= nullptr) return false;else if(left !=nullptr && right == nullptr) return false;else if(left ==nullptr && right ==nullptr) return true;else if(left->val != right->val) return false;//左右子树的内外侧比较bool outside = compare(left->left,right->right);bool inside = compare(left->right,right->left);return outside && inside;}bool isSymmetric(TreeNode* root) {return compare(root->left,root->right);}
};
做这两道题,感觉做对普通二叉树的一些性质的判断或者操作,可以优先考虑使用递归的思路,而想要用递归,得先找到递归的规律。