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)