Menu Tree Changes
MediumTrees · DoorDash
A restaurant menu is a tree. Each node is a dictionary {"key": str, "value": int, "active": bool, "children": [...]}: the root is the whole menu, inner nodes are categories, and leaves are items. A whole menu may also be None (no menu at all).
Given the old_menu and the new_menu, return the number of nodes that changed. Nodes are matched like this:
- The two roots match if they have the same
key. - Two children match if their parents match and they have the same
key. The order ofchildrendoes not matter, and sibling keys are unique.
Then count:
- every matched pair whose
valueoractivediffers, counted once per pair; - every node in the old menu with no match (it was removed), including all of its descendants;
- every node in the new menu with no match (it was added), including all of its descendants.
A node whose own fields changed does not make its children count as changed; they are still compared individually.
Example 1
- Input:
- old_menu = {"key": "menu", "value": 0, "active": True, "children": [{"key": "burgers", "value": 0, "active": True, "children": [{"key": "classic", "value": 899, "active": True, "children": []}, {"key": "veggie", "value": 999, "active": True, "children": []}]}, {"key": "drinks", "value": 0, "active": True, "children": [{"key": "cola", "value": 199, "active": True, "children": []}]}]}, new_menu = {"key": "menu", "value": 0, "active": True, "children": [{"key": "burgers", "value": 0, "active": True, "children": [{"key": "classic", "value": 949, "active": True, "children": []}, {"key": "veggie", "value": 999, "active": False, "children": []}]}, {"key": "sides", "value": 0, "active": True, "children": [{"key": "fries", "value": 349, "active": True, "children": []}]}]}
- Output:
- 6
- Explanation
classicchanged price andveggiewas deactivated (2). Thedrinkscategory was removed along withcola(2), andsideswas added along withfries(2), so 6 nodes changed.
Example 2
- Input:
- old_menu = {"key": "menu", "value": 0, "active": True, "children": [{"key": "tea", "value": 300, "active": True, "children": []}, {"key": "coffee", "value": 400, "active": True, "children": []}]}, new_menu = {"key": "menu", "value": 0, "active": True, "children": [{"key": "coffee", "value": 400, "active": True, "children": []}, {"key": "tea", "value": 300, "active": True, "children": []}]}
- Output:
- 0
- Explanation
- Children are matched by key, not by position, so swapping
teaandcoffeechanges nothing.
Example 3
- Input:
- old_menu = {"key": "menu", "value": 0, "active": True, "children": [{"key": "pizza", "value": 0, "active": True, "children": [{"key": "margherita", "value": 1200, "active": True, "children": []}]}]}, new_menu = {"key": "menu", "value": 0, "active": True, "children": [{"key": "pizza", "value": 0, "active": False, "children": [{"key": "margherita", "value": 1200, "active": True, "children": []}]}]}
- Output:
- 1
- Explanation
- Only the
pizzacategory's active flag changed. Its childmargheritais still matched and identical, so it does not count.
Constraints
- Each menu is
Noneor a tree with1 <= nodes <= 10^4 - Tree depth is at most
100 - Sibling keys are unique; keys are non-empty strings
0 <= value <= 10^6