文章目录
- 题目
- 标题和出处
- 难度
- 题目描述
- 要求
- 示例
- 数据范围
- 解法一
- 思路和算法
- 代码
- 复杂度分析
- 解法二
- 思路和算法
- 代码
- 复杂度分析
题目
标题和出处
标题:翻转二叉树
出处: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。