[LeetCode] 94. Binary Tree Inorder Traversal

Given the root of a binary tree, return the inorder traversal of its nodes' values.

Example 1:

Input: root = [1,null,2,3]
Output: [1,3,2]

Example 2:

Input: root = []
Output: []

Example 3:

Input: root = [1]
Output: [1]

Example 4:

Input: root = [1,2]
Output: [2,1]

Example 5:

Input: root = [1,null,2]
Output: [1,2]

Constraints:

  • The number of nodes in the tree is in the range [0, 100].
  • -100 <= Node.val <= 100

Follow up: Recursive solution is trivial, could you do it iteratively?

二叉树的中序遍历。

中序遍历我记为 左 - 根 - 右

还是用GeeksforGeeks的例子来描述如何做中序遍历吧。

Inorder (Left, Root, Right) : 4 2 5 1 3

树的遍历大部分都是可以给出迭代和递归两种做法的,此题我也给出两种做法。两种做法的时间和空间复杂度一样,时间都是O(n),空间都是O(h)。

迭代

(配合例子看)迭代的做法是需要将所有的左孩子先放进栈,这样弹出的时候(15行),最小的左孩子4就被存入结果集了。此时cur指针在stack顶端,2的位置,所以此时才会有17行去看2是否有右孩子。有的话,下一次while循环的一开头,这个右孩子5就会被再次放进栈。

JavaScript实现

 1 /**
 2  * @param {TreeNode} root
 3  * @return {number[]}
 4  */
 5 var inorderTraversal = function(root) {
 6     let res = [];
 7     if (root === null) return res;
 8     let stack = [];
 9     let cur = root;
10     while (cur !== null || stack.length) {
11         while (cur !== null) {
12             stack.push(cur);
13             cur = cur.left;
14         }
15         cur = stack.pop();
16         res.push(cur.val);
17         cur = cur.right;
18     }
19     return res;
20 };

Java实现

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null) return res;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root;
        while (cur != null || !stack.isEmpty()) {
            while (cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            res.add(cur.val);
            cur = cur.right;
        }
        return res;
    }
}

递归

递归的做法很直观,既然是中序遍历,所以根节点需要放在左孩子和右孩子的helper函数中间。

JavaScript实现

 1 /**
 2  * @param {TreeNode} root
 3  * @return {number[]}
 4  */
 5 var inorderTraversal = function(root) {
 6     let res = [];
 7     if (root === null) return res;
 8     helper(res, root);
 9     return res;
10 };
11 
12 var helper = function(res, root) {
13     if (root === null) return;
14     helper(res, root.left);
15     res.push(root.val);
16     helper(res, root.right);
17 };

Java实现

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode() {}
 8  *     TreeNode(int val) { this.val = val; }
 9  *     TreeNode(int val, TreeNode left, TreeNode right) {
10  *         this.val = val;
11  *         this.left = left;
12  *         this.right = right;
13  *     }
14  * }
15  */
16 class Solution {
17     public List<Integer> inorderTraversal(TreeNode root) {
18         List<Integer> res = new ArrayList<>();
19         if (root == null) {
20             return res;
21         }
22         helper(res, root);
23         return res;
24     }
25 
26     public static void helper(List<Integer> res, TreeNode root) {
27         if (root == null) {
28             return;
29         }
30         helper(res, root.left);
31         res.add(root.val);
32         helper(res, root.right);
33     }
34 }

关于为什么很多树的题目的空间复杂度是O(h) - 树的高度,我这里给一个discussion里面看到的截图。我看到这个截图我彻底懂了为什么是跟树的高度有关了。

树的遍历

94. Binary Tree Inorder Traversal

144. Binary Tree Preorder Traversal

145. Binary Tree Postorder Traversal

LeetCode 题目总结

原文地址:https://www.cnblogs.com/cnoodle/p/12174350.html