1

I'm trying to solve LeetCode 199.

Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

I've already solved this problem by using Level-Order-Traversal with time complexity of O(n) & memory complexity of O(n).

I'm wondering if it's possible to optimize the solution, and solve this problem iteratively with constant memory complexity of O(1) without using any data structure.

My solution with time & memory of O(n):

# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
 # time complexity: O(n), memory complexity: O(n)
 def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
 if not root: return []
 res = []
 q = collections.deque([root])
 while q:
 len_q, level = len(q), []
 for _ in range(len_q):
 node = q.popleft()
 level.append(node)
 if node.left: q.append(node.left)
 if node.right: q.append(node.right)
 res.append(level[-1].val) # add the last element of each level (right most element)
 return res
asked Aug 18 at 6:12
10
  • Have you checked other leetcode solutions? Commented Aug 18 at 6:17
  • 1
    You cannot traverse a tree in O(1) memory unless you are willing to temporarily modify the tree a la Morris traversal. Commented Aug 18 at 6:22
  • 1
    If you've "already seen tree solutions with constant memory complexity of O(1)" then why are you still "wondering if it is possible to do"? Commented Aug 18 at 6:38
  • 1
    Yes this modification may lead to a solution. Commented Aug 18 at 6:42
  • 1
    Just to come back to extending the tree with pointers to siblings: if these are added references (while still maintaining the left/right references), it is not an O(1) operation, as you would allocate an extra O(1) for each node. If however, you reuse the left/right references for another purpose (like linking to siblings), it is fine. Commented Aug 18 at 11:56

1 Answer 1

5

The memory allocated for the output can be used as a stack to trace the state of the depth-first traversal. Although that is O(n), this is memory that was needed anyway for the output. Besides that there is only O(1) of auxiliary memory used.

Some specifics about that stack:

  • If a node has two children, then put the node (reference) on the stack so to indicate we later still need to visit its right child
  • If a node has just one child, then put the node's value on the stack so we know there are no other children to visit, and this value can serve as part of the output
  • Whenever you pop from the stack, only modify a stack index, but don't actually remove the popped value from the list that backs this stack. That way, that list retains the expected values, even as the stack is emptied.

Here is how you could implement that:

"""
A stack implementation that never really deletes values as we pop, 
but only adjusts a size attribute. 
This way the backing list will retain for each depth the last value 
that was on the stack at that depth.
""" 
class Stack(list):
 def __init__(self):
 super().__init__()
 self.size = 0
 
 def push(self, value):
 if len(self) == self.size:
 self.append(value)
 else:
 self[self.size] = value
 self.size += 1
 def pop(self):
 if self.size:
 self.size -= 1
 return self[self.size]
class Solution:
 def rightSideView(self, node: Optional[TreeNode]) -> List[int]:
 stack = Stack()
 while True:
 # Follow path down the tree to the left-most leaf
 while node:
 stack.push(node if node.left and node.right else node.val)
 node = node.left or node.right
 # Backtrack up the tree to a node whose second child has not been explored
 node = stack.pop()
 while node is not None and not isinstance(node, TreeNode):
 node = stack.pop()
 if node is None: # all done
 return stack # this is a list of values overloaded with a size attribute
 # Go down into the right subtree
 stack.push(node.val)
 node = node.right
answered Aug 18 at 11:00
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.