一、题目描述
翻转一棵二叉树。
输入:
4
/ \
2 7
/ \ / \
1 3 6 9
输出:
4
/ \
7 2
/ \ / \
9 6 3 1
备注:
这个问题是受到 Max Howell 的 原问题 启发的 :
谷歌:我们90%的工程师使用您编写的软件(Homebrew),
但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。
二、题解
方法一:前序遍历(根左右)
public TreeNode invertTree(TreeNode root) {
dfs(root);
return root;
}
//前序遍历:根左右
private void preOrder(TreeNode root) {
if (root == null)
return;
TreeNode t = root.right;
root.right = root.left;
root.left = t;
preOrder(root.left);
preOrder(root.right);
}
非递归
private void preOrder(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
if (node == null)
continue;
TreeNode t = node.left;
node.left = node.right;
node.right = t;
stack.push(node.right);
stack.push(node.left); //先取出做子树
}
}
复杂度分析
- 时间复杂度: ,N 是树中节点的个数,类似树的遍历。
- 空间复杂度: ,
方法二:中序(左根右)
private void inOrder(TreeNode root) {
if (root == null)
return;
//递归找到左节点,实际上左叶子结点的交换是徒劳的
inOrder(root.left);
TreeNode t = root.right;
root.right = root.left;
root.left = t;
//递归找到右叶子,因为交换过
inOrder(root.left);
}
复杂度分析
- 时间复杂度: ,N 是树中节点的个数,类似树的遍历。
- 空间复杂度: ,
方法三:后序(左右根)
private void postOrder(TreeNode root) {
if (root == null)
return;
dfs(root.left);
dfs(root.right);
TreeNode t = root.right;
root.right = root.left;
root.left = t;
}
复杂度分析
- 时间复杂度: ,N 是树中节点的个数,类似树的遍历。
- 空间复杂度: ,
方法四:层序遍历
private void levelOrder(TreeNode root) {
if (root == null)
return;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
TreeNode t = node.left;
node.left = node.right;
node.right = t;
//注:左右子树整体已经交换
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
}
复杂度分析
- 时间复杂度: ,N 是树中节点的个数,类似树的遍历。
- 空间复杂度: ,