Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree [1,null,2,3]
,
1 \ 2 / 3
return [1,3,2]
.
Note: Recursive solution is trivial, could you do it iteratively?
通常,实现二叉树的前序(preorder)、中序(inorder)、后序(postorder)遍历有两个常用的方法:一是递归(recursive),二是使用栈实现的迭代版本(stack+iterative)。这两种方法都是O(n)的空间复杂度(递归本身占用stack空间或者用户自定义的stack)
Recursive: Runtime: 1 ms beats 60.97% of javasubmissions.
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) return res;
res.addAll(inorderTraversal(root.left));
res.add(root.val);
res.addAll(inorderTraversal(root.right));
return res;
}
Iterative with Stack. Runtime: 2 ms beats 4.67% of javasubmissions.
public List<Integer> inorderTraversal2(TreeNode root) {
List<Integer> results = new ArrayList<>();
ArrayDeque<TreeNode> stack = new ArrayDeque<>();
TreeNode crt = root;
while (!stack.isEmpty() || crt != null) {
if (crt != null) {
stack.push(crt);
crt = crt.left;
} else {
crt = stack.pop();
results.add(crt.val);
crt = crt.right;
}
}
return results;
}
Morris Traversal(threaded binary tree)方法遍历二叉树(非递归,不用栈,O(1)空间)中序遍历,时间复杂度 O(n).
Recursive:
Runtime:
1 ms beats 60.97% of javasubmissions.
public List<Integer> inorderTraversal3(TreeNode root) {
List<Integer> results = new ArrayList<>();
TreeNode crt = root;
while (crt != null) {
if (crt.left == null) {
results.add(crt.val);
crt = crt.right;
} else {
TreeNode temp = crt.left;/* 查找前驱 */
while (temp.right != null && temp.right != crt)
temp = temp.right;
if (temp.right == null) {/* 还没线索化,则建立线索 */
temp.right = crt;
crt = crt.left;
} else {/* 已经线索化,则访问节点,并删除线索 */
temp.right = null;
results.add(crt.val);
crt = crt.right;
}
}
}
return results;
}