给你一棵二叉树的根节点
root
,翻转这棵二叉树,并返回其根节点。示例 1:
输入:root = [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2:
输入:root = [2,1,3] 输出:[2,3,1]示例 3:
输入:root = [] 输出:[]提示:
- 树中节点数目范围在
[0, 100]
内-100 <= Node.val <= 100
背景:
一位大佬吐槽自己面试Google,因为没写出翻转二叉树被拒了,Leetcode 很快收录了这道题。
思路:
参考 LeetCode题解
- 解法1 递归
- 终止条件:当前节点为
null
时返回 - 交换当前节点的左右节点,再递归的交换当前节点的左节点,递归的交换当前节点的右节点
- 终止条件:当前节点为
- 解法2 迭代
-
用层序遍历的方式去遍历二叉树。
根节点先入列,然后出列,出列就 “做事”,交换它的左右子节点(左右子树)。
并让左右子节点入列,往后,这些子节点出列,也被翻转。
直到队列为空,就遍历完所有的节点,翻转了所有子树。解决问题的代码放在节点出列时。
-
时间复杂度:
- 递归:O(n),每个元素都必须访问一次
- 迭代:O(n)
空间复杂度:
- 递归:O(n),最坏的情况下,树为链表形态,递归栈的深度为O(n)(n是 树高度/链表长度)
- 迭代:O(n),比如一颗只有根节点的树,其对应的队列长度也为1
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
// 解法1 递归(dfs)
func invertTree(root *TreeNode) *TreeNode {
// 方式1 非闭包
if root == nil {
return nil
}
root.Left, root.Right = root.Right, root.Left
invertTree(root.Left)
invertTree(root.Right)
return root
// 方式2 闭包
// var recur func(root *TreeNode)
// recur = func(root *TreeNode) {
// if root == nil {
// return
// }
// root.Left, root.Right = root.Right, root.Left
// recur(root.Left)
// recur(root.Right)
// return
// }
// recur(root)
// return root
}
// 解法2 迭代(bfs)
func invertTree(root *TreeNode) *TreeNode {
if root == nil {
return root
}
queue := make([]*TreeNode, 0)
queue = append(queue, root)
for len(queue) > 0 {
tmp := queue[0] // 这里新建一个变量来接收队头节点,而不应改变root对象值
queue = queue[1:] // pop
tmp.Left, tmp.Right = tmp.Right, tmp.Left
if tmp.Left != nil {
queue = append(queue, tmp.Left)
}
if tmp.Right != nil {
queue = append(queue, tmp.Right)
}
}
return root
}