Boolean Expression Tree with Leaf Flips
GoogleSoftware Engineer · OnsiteLast updated
This problem tests recursive tree evaluation logic and the ability to optimize updates by propagating changes only to necessary ancestors.
Problem Statement
You are given a binary expression tree representing a boolean expression. The leaves of the tree are boolean values (True or False), and the internal nodes are logical operators (AND, OR).
Implement a structure that supports two operations:
evaluate(): Returns the current boolean result of the root.flip(leaf_id): Toggles the boolean value of the leaf with the given ID.
Each node in the tree has a unique id. Internal nodes maintain the result of their children based on their operator. You must optimize the flip operation so that it does not re-evaluate the entire tree.
Function Signature
class Node:
def __init__(self, id, type, left=None, right=None, val=None):
self.id = id
self.type = type # 'AND', 'OR', or 'LEAF'
self.left = left
self.right = right
self.val = val # Only for LEAF nodes
Constraints
- The tree is a full binary tree (every internal node has two children).
flipmust run inO(h)time, wherehis the height of the tree.evaluatemust run inO(1)time.
Example
Consider: Root(AND) -> Left(LEAF: True), Right(OR) -> (LEAF: False, LEAF: True)
- Initial evaluation:
True AND (False OR True)=True. flip(Right-Left): TheFalsebecomesTrue.- The tree updates:
RightbecomesTrue,RootremainsTrue.
Edge Cases
- Single node trees (leaf only).
- Logical short-circuiting: Note that
ANDcan beFalseeven if one child isFalseregardless of the other, but for this problem, assume nodes update based on both children values unless optimized.
Hints
Hint 1
Store the current evaluated boolean value at every internal node to allow O(1) evaluation at the root.
Hint 2
Maintain a parent pointer for each node to allow traversing upwards from a flipped leaf to the root.
Hint 3
During a flip, update the path from the leaf to the root; stop propagating the update if the internal node's calculated value does not change.
Follow-up questions
- How would your approach change if you added a NOT operator node that has only one child?
- What is the impact on complexity if the tree becomes highly unbalanced or degenerate?
- How would you handle concurrent updates to different leaves if multiple threads were involved?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.