Given the root of a tree root, return an array containing the postorder traversal of the tree.
Write the solution using iterative code - do not use recursion.
postorderTraversal(TreeNode.of([1, 2, 3, 4, 5, 6, 7]))
# [4, 5, 2, 6, 7, 3, 1]postorderTraversal(TreeNode.of([1, 2, 3]))
# [2, 3, 1]postorderTraversal(TreeNode.of([5, 7, 2, 3, None, None, 1]))
# [3, 7, 1, 2, 5]Here's the code for a recursive inorder traversal:
traversal = []
def visitAll(node):
if node is None: # base case
return
visitAll(node.left)
visitAll(node.right)
traversal.append(node.val)In this problem, we need to write the same code but without using a recursive function. As usual, this means you need to implement the recursive code using your own stack, instead of using the computer's Call Stack.
The trick to doing this is keep track of whether you're visiting each node for the first time. The first time you visit a node, you should not act on the node, and should instead first run visitAll on the node's left and right children, and then come back to the current node. The next time you visit a node, you're ready to act on it (add it to the traversal).
Here's the code:
# Iterative postorder traversal
def postorderTraversal(root):
traversal = []
stack = [(root, True)]
while stack:
# take a node off the stack and visit it
node, isFirstCall = stack.pop()
if node is None:
continue
# call left and then call right and then come back
if isFirstCall:
stack.append((node, False))
stack.append((node.right, True)) # right needs to be put in stack first
stack.append((node.left, True))
else:
# when we come back, add this node to the traversal
traversal.append(node.val)
return traversalTime Complexity O(n)
Space Complexity O(n) The stack takes up as much space as the Call Stack would have if we wrote this recursively, since the stack is just our own version of the Call Stack. This means stack can get n calls deep, requiring O(n) space.