LeedCode 94:二叉树的中序遍历

197 阅读2分钟

LeedCode 94:二叉树的中序遍历

题目描述:

给定一个二叉树的根节点 root ,返回它的 中序 遍历。

示例1

输入: root = [1,null,2,3]
输出: [1,3,2]

示例2

输入: root = []
输出: []

示例3

输入: root = [1]
输出: [1]

示例4

输入: root = [1,2]
输出: [2,1]

解题思路 

先来了解下二叉树的中序遍历:
按照访问左子树——根节点——右子树的方式遍历这棵树

思路一: 递归

定义 inorderTraversalNode(node) 表示当前遍历到 node 节点的值,那么按照遍历方式,我们只要递归调用 inorderTraversalNode(node.left) 来遍历 node 节点的左子树,然后将 node 节点的值加入result,inorderTraversalNode(node.right) 来遍历 node 节点的右子树即可,递归终止的条件为碰到空节点。

实现代码如下:

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function (root) {
  var result = [];
  var inorderTraversalNode = function (node) {
    if (node) {
      // 先左子树
      inorderTraversalNode(node.left);
      // 再根节点
      result.push(node.val);
      // 最后遍历右子树
      inorderTraversalNode(node.right);
    }
  }
  inorderTraversalNode(root);
  return result;
};

时间复杂度: O(n),其中 n 是二叉树的节点数, 二叉树的遍历中每个节点会被访问一次且只会被访问一次

空间复杂度: O(n), 空间复杂度取决于递归的栈深度,而栈深度在二叉树为一条链的情况下会达到 O(n) 的级别

思路二: 迭代

区别在于递归的时候隐式地维护了一个栈,而我们在迭代的时候需要显式地将这个栈模拟出来, 使用数组的pop、push方法;

实现代码如下:

/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function (root) {
  var result = [], stack = [], node = root;
  while (node || stack.length) {
    while (node) {
      stack.push(node);
      node = node.left;
    }
    node = stack.pop();
    result.push(node.val);
    node = node.right;
  }
  return result;
};

时间复杂度:O(n),其中 n 是二叉树的节点数, 二叉树的遍历中每个节点会被访问一次且只会被访问一次

空间复杂度:O(n)

参考资料

LeetCode94.二叉树的中序遍历 - 力扣(LeetCode)