给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
// return postorderTraversalI(root);
// return postorderTraversalII(root);
// return postorderTraversalIII(root);
return postorderTraversalIIII(root);
}
//方法四:迭代,时间和空间复杂度O(N),与方法三类似,但是不用反转
private List<Integer> postorderTraversalIIII(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
//后序遍历当遍历完右子树时会回到根节点,这个时候不需要操作,直接退回到上一层即可
//所以定义prev记录上一次遍历过的节点
TreeNode prev = null;
while (!stack.isEmpty() || root != null) {
//先不不断遍历左子树并入栈
while (root != null) {
stack.push(root);
root = root.left;
}
//左子树遍历到叶子节点时,返回栈顶元素
TreeNode node = stack.peek();
//当右子树不为null且是第一次遍历的时候,回到右子树继续遍历
if (node.right != null && node.right != prev) {
root = node.right;
} else {
//否则遍历结束或第二次遍历时将节点值加入结果集,更新prev节点
list.add(node.val);
prev = node;
//出栈回到上一层
stack.pop();
}
}
return list;
}
//方法三:迭代,时间和空间复杂度O(N),与方法二类似
//前序遍历是先遍历左子树,这里先遍历右子树
private List<Integer> postorderTraversalIII(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty() || root != null) {
while (root != null) {
stack.push(root);
list.add(root.val);
root = root.right;
}
TreeNode node = stack.pop();
root = node.left;
}
Collections.reverse(list);
return list;
}
//方法二:迭代,时间和空间复杂度O(N)
//后序遍历是左右根,反转后则变成根右左,而前序遍历是根左右
//所以可以按照前序遍历的思路,先遍历左子树,然后将结果反转即可得到后序遍历
private List<Integer> postorderTraversalII(TreeNode root) {
List<Integer> list = new ArrayList<>();
if (root == null) {
return list;
}
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();
list.add(0, node.val);
//前序遍历是先遍历右子树,这里则是先遍历左子树
if (node.left != null) {
stack.push(node.left);
}
if (node.right != null) {
stack.push(node.right);
}
}
return list;
}
//方法一:递归,时间和空间复杂度O(N)
private List<Integer> postorderTraversalI(TreeNode root) {
List<Integer> list = new ArrayList<>();
helper(root, list);
return list;
}
private void helper(TreeNode root, List<Integer> list) {
if (root == null) {
return;
}
helper(root.left, list);
helper(root.right, list);
list.add(root.val);
}
}