翻转二叉树
题目描述:
翻转一棵二叉树。
示例 1:
输入:4 / \ 2 7 / \ / \ 1 3 6 9
输出:
4 / \ 7 2 / \ / \ 9 6 3 1
解题思路
思路一: 递归/深度优先遍历
先交换一下左右节点,然后再递归的交换左节点,右节点
递归的两个条件如下:
- 终止条件:当前节点为 null 时返回
- 交换当前节点的左右节点,再递归的交换当前节点的左节点,递归的交换当前节点的右节点
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var invertTree = function(root) {
// 递归函数的终止条件,节点为空时返回
if (root === null) return null;
// 下面三句是将当前节点的左右子树交换
var tmp = root.left;
root.left = root.right;
root.right = tmp;
// 递归交换当前节点的左子树
invertTree(root.left);
// 递归交换当前节点的右子树
invertTree(root.right);
return root;
};
时间复杂度: O(n)
空间复杂度: O(n)
思路二:迭代/ 广度优先遍历
广度优先遍历需要额外的数据结构--队列,来存放临时遍历到的元素。
深度优先遍历的特点是一竿子插到底,不行了再退回来继续;而广度优先遍历的特点是层层扫荡。
所以,我们需要先将根节点放入到队列中,然后不断的迭代队列中的元素。
对当前元素调换其左右子树的位置,然后:
- 判断其左子树是否为空,不为空就放入队列中
- 判断其右子树是否为空,不为空就放入队列中
var invertTree = function(root) {
if (root === null) return null;
// 将二叉树中的节点逐层放入队列中,再迭代处理队列中的元素
var queue = [root];
while (queue.length) {
// 每次都从队列中拿一个节点,并交换这个节点的左右子树
var node = queue.pop();
var tmp = node.left;
node.left = node.right;
node.right = tmp;
// 如果当前节点的左子树不为空,则放入队列等待后续处理
if(node.left !== null) {
queue.push(node.left);
}
// 如果当前节点的右子树不为空,则放入队列等待后续处理
if(node.right !== null) {
queue.push(node.right);
}
}
// 返回处理完的根节点
return root;
};
时间复杂度:O(n)
空间复杂度:O(n)