Count Good Nodes in Binary Tree
1Try it yourself first
Think for 20-30 minutes before you open any hint. Being stuck is where the learning happens.
Only for you, saved in this browser. After you see the approach you will compare it with your idea.2What is being asked
A node is "good" if no node on the path from the root to it has a larger value. Count the good nodes.
3Hint ladder
Take one rung at a time. Stop as soon as the idea clicks.
- Hint 1What single number about the path so far decides whether the current node is good?
- Hint 2Pass the maximum so far down to both children.
4The approach
Have you tried the hints? The approach is built as a path from the obvious way to the clever one.
Hiking up a mountain trail: a spot is a "viewpoint" only if nobody standing on the trail before it is higher than you (nothing blocks your view backwards). As you walk, you carry the highest altitude you have passed so far. A new spot at least as high as that is a viewpoint, and then your remembered highest altitude goes up.
- The obvious way
For each node walk back up to the root checking its ancestors: O(n x height).
- The key insight
Carry down the largest value seen on the path. If the current node's value is at least that largest, it is good: count it. The new largest for the children is the bigger of the two. One visit per node.
- The algorithm
- Start at the root with the largest so far = negative infinity.
- Node value >= largest so far? It is good: count 1.
- New largest = max(largest, node value).
- Add the good counts of the left and right subtrees.
Watch it run
Exampletree = [3, 1, 4, 3, null, 1, 5]
The root 3 is always good. Largest so far: 3.
good: 1
Where people slip
- ">= " not ">": a node equal to the largest so far is still good.
How close was your idea?
You did not write an idea, and that is fine.
Be honest with yourself. This sets your revision list.
5Code
Try writing it yourself from the steps first. Then compare.
def good_nodes(root):
def count(node, highest):
if node is None:
return 0
good = 1 if node.val >= highest else 0 # no one on the path is higher
highest = max(highest, node.val)
return good + count(node.left, highest) + count(node.right, highest)
return count(root, float("-inf"))Now close this and write it again from memory, in the language you will use in the interview. Reattempt after 1 day, 7 days and about 30 days.
6Still stuck? Watch a video
Seeing someone explain it out loud can make it click. Try the video after you have read the approach above.