题目
标题和出处
标题:翻转二叉树
出处:226. 翻转二叉树
难度
3 级
题目描述
要求
给定二叉树的根结点 root \texttt{root} root,翻转二叉树,并返回其根结点。
示例
示例 1:
输入:
root
=
[4,2,7,1,3,6,9]
\texttt{root = [4,2,7,1,3,6,9]}
root = [4,2,7,1,3,6,9]
输出:
[4,7,2,9,6,3,1]
\texttt{[4,7,2,9,6,3,1]}
[4,7,2,9,6,3,1]
示例 2:
输入:
root
=
[2,1,3]
\texttt{root = [2,1,3]}
root = [2,1,3]
输出:
[2,3,1]
\texttt{[2,3,1]}
[2,3,1]
示例 3:
输入:
root
=
[]
\texttt{root = []}
root = []
输出:
[]
\texttt{[]}
[]
数据范围
- 树中结点数目在范围 [0, 100] \texttt{[0, 100]} [0, 100] 内
- -100 ≤ Node.val < 100 \texttt{-100} \le \texttt{Node.val} < \texttt{100} -100≤Node.val<100
解法一
思路和算法
如果二叉树为空,则空二叉树翻转之后仍为空二叉树,不需要执行翻转操作。
当二叉树不为空时,翻转二叉树的操作为首先交换根结点的左右子树,然后对左右子树分别翻转。
翻转二叉树的过程是一个递归的过程,递归的终止条件是当前二叉树为空。当二叉树不为空时,首先交换当前二叉树的左右子树,然后对左右子树调用递归完成翻转,即可完成二叉树的翻转。
代码
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
TreeNode left = root.left;
TreeNode right = root.right;
root.left = right;
root.right = left;
invertTree(root.left);
invertTree(root.right);
return root;
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次,对于每个结点交换左右子树的时间都是 O ( 1 ) O(1) O(1)。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间,取决于二叉树的高度,最坏情况下二叉树的高度是 O ( n ) O(n) O(n)。
解法二
思路和算法
由于翻转二叉树等价于对二叉树中的每个结点交换左右子树,因此基于该思路,也可以使用广度优先搜索翻转二叉树。
初始时将根结点入队列,遍历过程中,每次将一个结点出队列,对于每个访问到的结点,将其左右子树交换,然后将非空子结点入队列继续遍历,直到队列为空时遍历结束,此时二叉树翻转完毕。
代码
class Solution {
public TreeNode invertTree(TreeNode root) {
if (root == null) {
return null;
}
Queue<TreeNode> queue = new ArrayDeque<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
TreeNode left = node.left, right = node.right;
node.left = right;
node.right = left;
if (right != null) {
queue.offer(right);
}
if (left != null) {
queue.offer(left);
}
}
return root;
}
}
复杂度分析
-
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次,对于每个结点交换左右子树的时间都是 O ( 1 ) O(1) O(1)。
-
空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是队列空间,队列内元素个数不超过 n n n。