LeetCode 226: 翻转二叉树

164 阅读2分钟

 翻转二叉树

题目描述:

翻转一棵二叉树。 

示例 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)

参考资料

226. 翻转二叉树 - 力扣(LeetCode) (leetcode-cn.com)