力扣 - 145. 二叉树的后序遍历
题目
思路1(递归)
- 中序先遍历左孩子,然后右孩子,最后父节点
- 递归遍历
代码
class Solution {
List<Integer> res = new ArrayList<>();
public List<Integer> postorderTraversal(TreeNode root) {
postOrder(root);
return res;
}
public void postOrder(TreeNode root) {
if (root == null) {
return;
}
postOrder(root.left);
postOrder(root.right);
res.add(root.val);
}
}
复杂度分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(N)\)
思路2(迭代)
- 用栈遍历
代码
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Deque<TreeNode> stack = new LinkedList<>();
TreeNode pre = null;
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
if (root.right == null || root.right == pre) {
res.add(root.val);
pre = root;
root = null;
} else {
stack.push(root);
root = root.right;
}
}
return res;
}
}
复杂度分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(N)\)
思路3(Morris遍历)
- 代码结构就是Morris的前序遍历
- 把原来所有的
right
改成left
,把原来所有的left
改成right
- 返回结果之前反转一下数组
代码
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList<>();
if (root == null) {
return res;
}
TreeNode p1 = root;
TreeNode p2 = null;
while (p1 != null) {
p2 = p1.right;
if (p2 != null) {
while (p2.left != null && p2.left != p1) {
p2 = p2.left;
}
if (p2.left == null) {
res.add(p1.val);
p2.left = p1;
p1 = p1.right;
continue;
} else {
p2.left = null;
}
} else {
res.add(p1.val);
}
p1 = p1.left;
}
Collections.reverse(res);
return res;
}
}
复杂度分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(1)\)
我走得很慢,但我从不后退!