「剑指 Offer 27.二叉树的镜像」
题目描述(level 简单)
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
示例
例如输入:
4
/ \
2 7
/ \ / \
1 3 6 9
镜像输出:
4
/ \
7 2
/ \ / \
9 6 3 1
示例 1:
输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]
限制:0 <= 节点个数 <= 1000
思路分析(BFS)
输出二叉树
的镜像,根据题目意思,即对于任意一个节点将其左右节点进行交换即可。而对于二叉树的遍历问题自然会想到广度优先搜索的层序遍历BFS,以及深度优先的DFS。先考虑使用BFS广度优先搜索,借助队列来实现:
- 初始化队列,添加入根节点
root
。 - 循环遍历,交换左右节点,直到遍历完整颗树。
- 返回修改后的二叉树
root
。
代码实现
public class Solution {
public TreeNode mirrorTree(TreeNode root) {
if (null == root) {
return null;
}
Queue<TreeNode> queue = new LinkedList<>();
//加入根节点
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
//判断是否有左节点并加入到队列
if (null != node.left) {
queue.add(node.left);
}
//判断是否有右节点并加入到队列
if (null != node.right) {
queue.add(node.right);
}
//交换操作
TreeNode temp = node.left;
node.left = node.right;
node.right = temp;
}
return root;
}
}
这里其实并没有用到特列的特性,使用栈也是同样的效果
思路分析(递归)
递归的出口很容易找到当null == root
是退出递归。写递归时,其实总有一个误区,就是想在大脑中将递归的过程平铺开来。递归本身就是无限套娃,想再大脑中模拟,往往会陷入死胡同。当然递归本身就存在两个过程:递推、回溯。只需要找到出口,需要干什么,中间的过程可不必过于纠结。
代码实现
public class Solution {
public TreeNode mirrorTree(TreeNode root) {
if (null == root) {
return null;
}
TreeNode leftNode = mirrorTree(root.left);
TreeNode rightNode = mirrorTree(root.right);
root.left = rightNode;
root.right = leftNode;
return root;
}
}
//简化后
public class Solution {
public TreeNode mirrorTree(TreeNode root) {
if (null == root) {
return null;
}
TreeNode leftNode = mirrorTree(root.left);
root.left = mirrorTree(root.right);
root.right = leftNode;
return root;
}
}
复杂度
时间复杂度(递归与辅助队列)O(N):均需要遍历整颗树的节点。
空间复杂度(递归与辅助队列)O(N):考虑到二叉树退化成链表的情况。