NC72 二叉树的镜像
题意
操作给定的二叉树,将其变换为源二叉树的镜像。
1. 魔改交换变量(前序遍历1)
我们在大一的C语言课上学过,交换两个变量a和b的代码是:
int c = a; a = b; b = c;
这道题跟交换两个变量差不多,稍微魔改一下上面的交换过程,把左孩子赋值为右子树的镜像, 右孩子赋值为左子树的镜像,就可以了。
注意这里不是赋值为右子树,而是右子树的镜像。
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param pRoot TreeNode类 * @return TreeNode类 */ using PNode = TreeNode*; TreeNode* Mirror(TreeNode* pRoot) { if (!pRoot) return nullptr; // 空树 // 魔改的交换两个变量 PNode temp = pRoot->left; pRoot->left = Mirror(pRoot->right); pRoot->right = Mirror(temp); return pRoot; } };
- 时间复杂度: . 每个点遍历了一次
- 空间复杂度: . 每个点递归了一次,每层的空间复杂度为
2. 层序遍历bfs
本题要求的是输出二叉树的镜像,就是每一个节点的左右子节点进行交换,再交换孩子的左右节点。
那么按“辈分”遍历,首先想到的思路就是bfs,本题可以用bfs解决。随便画一个二叉树看下:
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param pRoot TreeNode类 * @return TreeNode类 */ using PNode = TreeNode*; TreeNode* Mirror(TreeNode* pRoot) { if (!pRoot) return nullptr; // 特判空树,考虑边界情况 queue<PNode> q; q.push(pRoot); while (!q.empty()) { PNode p = q.front(); q.pop(); // 交换当前节点的左右子节点 swap(p->left, p->right); // 继续遍历下一层 if (p->left) q.push(p->left); if (p->right) q.push(p->right); } return pRoot; } };
- 时间复杂度: O(n). 每个点遍历了一次
- 空间复杂度: O(n). 定义了大小为n的队列。
3. 前序遍历2/中序/后序遍历法
方法一相当于前序遍历,方法二相当于层次遍历,实际上中序/后序遍历也可以解决这道题。anyway,遍历到的每个点都将其左右互换就可以了。
class Solution { public: // 后序遍历法 using PNode = TreeNode*; TreeNode* Mirror(TreeNode* pRoot) { if (!pRoot) return nullptr; Mirror(pRoot->left); Mirror(pRoot->right); swap(pRoot->left, pRoot->right); // 把这句话放到第8行上面,也可以作为另一种前序遍历的解法 return pRoot; } };
class Solution { public: // 中序遍历法 using PNode = TreeNode*; TreeNode* Mirror(TreeNode* pRoot) { if (!pRoot) return nullptr; Mirror(pRoot->left); swap(pRoot->left, pRoot->right); Mirror(pRoot->left); // 需要注意,left和right互换了,所以递归右子树要写left。 return pRoot; } };
- 时间、空间复杂度同方法一。
4. 总结
本题方法较多,也较为简单,用各种遍历法均能解决,是复习二叉树各种遍历方式的一道很基础的好题。