Talentd
FleetCode
Make and follow sheets.Sign in

Count Dominant Nodes in a Binary Tree solution and explanation

MediumBinary TreeDepth-First SearchTree4 min read72.1% acceptanceUpdated 27 Jul 2026
3997. Count Dominant Nodes in a Binary Tree (Leetcode Medium)Programming Live with Larry · 5:23 · 78 viewsWatch on YouTube
4 more videos on this problem
  1. 3997. Count Dominant Nodes in a Binary Tree (Leetcode Medium)Programming Live with Larry · 5:23 · 78 views
  2. LeetCode 3997 | Count Dominant Nodes in a Binary Tree | Postorder DFS | JavaCode Kage · 8:45 · 74 views
  3. Leetcode contest 511 - 3997 - Count Dominant Nodes in a Binary TreeManjeet Dhayal · 3:51 · 37 views
  4. Leetcode 3997. Count Dominant Nodes in a Binary Tree | DFS | Tree | MediumLeet's Code · 20:49 · 31 views
  5. Count Dominant Nodes in a Binary Tree ( LeetCode 3997 C++ )AeXel · 8:56 · 28 views

The problem

You are given the root of a complete binary tree.

A node x is called dominant if its value is equal to the maximum value among all nodes in the subtree rooted at x.

Return the number of dominant nodes in the tree.

Example 1:

Input: root = [5,3,8,2,4,7,1]

Output: 5

Explanation:

  • The leaf nodes with values 2, 4, 7, and 1 are dominant.
  • The node with value 8 is dominant because its value is the maximum value in its subtree [8, 7, 1].
  • Thus, the answer is 5.

Example 2:

Input: root = [1,2,3,1,2]

Output: 4

Explanation:

  • The leaf nodes with values 1, 2, and 3 are dominant.
  • The node with value 2 whose subtree is [2, 1, 2] is dominant because its value is the maximum value in its subtree.
  • Thus, the answer is 4.

Constraints:

  • The number of nodes in the tree is in the range [1, 105].
  • 1 <= Node.val <= 109
  • The tree is guaranteed to be a complete binary tree.

Approach overview

Problem Overview: You need to count how many nodes in a binary tree are dominant. A node is dominant if its value is greater than or equal to every value on the path from the root to that node. The main challenge is tracking the maximum value seen so far while traversing the tree.

Approach 1: Path Recalculation DFS (O(nh) time, O(h) space)

This brute force approach checks every node by recomputing the maximum value along the root-to-node path. You perform a DFS traversal and maintain the current path in an array or stack. For each node, iterate through the stored path to verify whether the node is dominant. This approach is useful for understanding the condition definition, but repeated path scans make it inefficient on skewed trees where height h becomes large.

Approach 2: DFS with Running Maximum (O(n) time, O(h) space)

The optimal solution uses Depth First Search and carries the maximum value seen so far during recursion. At each node, compare node.val with maxSoFar. If the current value is greater than or equal to the running maximum, increment the answer. Then recurse into the left and right subtrees with max(maxSoFar, node.val). Every node is visited exactly once, which gives linear time complexity.

This approach works naturally with recursive Binary Tree traversal because each recursive call already represents a root-to-node path. You avoid extra storage for full paths and reduce repeated comparisons. The recursion stack uses at most O(h) space, where h is the tree height.

Approach 3: Iterative DFS with Stack (O(n) time, O(h) space)

If recursion depth is a concern, you can simulate DFS using an explicit stack. Store pairs of (node, maxSoFar) while traversing the tree. Pop a node, evaluate whether it is dominant, update the running maximum, and push its children onto the stack. This iterative version avoids recursion limits and still preserves the same asymptotic complexity.

Recommended for interviews: Interviewers typically expect the DFS with running maximum approach. The brute force solution demonstrates understanding of the dominant-node condition, but the optimized DFS shows you can eliminate redundant work using state propagation during traversal. Recursive DFS is usually the cleanest implementation, while iterative DFS is preferred when stack overflow is a concern.

Solution

A node is dominant if its value equals the maximum value in the subtree rooted at it. Therefore, for each node, we only need the maximum values of its left and right subtrees, then compare them with the node itself.

Perform a bottom-up DFS: return -infty for a null node (implemented with the language's minimum integer value), and for the current node compute mx = max(leftMax, rightMax, node.val). If mx = node.val, the node is dominant and the answer is incremented by one. Finally return mx for the parent node.

The time complexity is O(n), and the space complexity is O(n), where n is the number of nodes in the tree.

# 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:
    def countDominantNodes(self, root: TreeNode | None) -> int:
        def dfs(node: TreeNode | None) -> int:
            if node is None:
                return -inf
            l = dfs(node.left)
            r = dfs(node.right)
            mx = max(l, r, node.val)
            if mx == node.val:
                nonlocal ans
                ans += 1
            return mx

        ans = 0
        dfs(root)
        return ans
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private int ans;

    public int countDominantNodes(TreeNode root) {
        dfs(root);
        return ans;
    }

    private int dfs(TreeNode node) {
        if (node == null) {
            return Integer.MIN_VALUE;
        }
        int l = dfs(node.left);
        int r = dfs(node.right);
        int mx = Math.max(Math.max(l, r), node.val);
        if (mx == node.val) {
            ++ans;
        }
        return mx;
    }
}
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int countDominantNodes(TreeNode* root) {
        int ans = 0;
        auto dfs = [&](this auto&& dfs, TreeNode* node) -> int {
            if (!node) {
                return INT_MIN;
            }
            int l = dfs(node->left);
            int r = dfs(node->right);
            int mx = max({l, r, node->val});
            if (mx == node->val) {
                ++ans;
            }
            return mx;
        };
        dfs(root);
        return ans;
    }
};
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */

function countDominantNodes(root: TreeNode | null): number {
    let ans = 0;
    const dfs = (node: TreeNode | null): number => {
        if (!node) {
            return -Infinity;
        }
        const l = dfs(node.left);
        const r = dfs(node.right);
        const mx = Math.max(l, r, node.val);
        if (mx === node.val) {
            ++ans;
        }
        return mx;
    };
    dfs(root);
    return ans;
}
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func countDominantNodes(root *TreeNode) int {
	ans := 0
	var dfs func(*TreeNode) int
	dfs = func(node *TreeNode) int {
		if node == nil {
			return math.MinInt32
		}
		l := dfs(node.Left)
		r := dfs(node.Right)
		mx := max(l, r, node.Val)
		if mx == node.Val {
			ans++
		}
		return mx
	}
	dfs(root)
	return ans
}
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Path Recalculation DFSO(nh)O(h)Useful for understanding the problem before optimization
DFS with Running MaximumO(n)O(h)Best general solution for interviews and production code
Iterative DFS with StackO(n)O(h)Preferred when recursion depth may exceed language stack limits

Frequently asked questions

Is Count Dominant Nodes in a Binary Tree easy or hard?

Count Dominant Nodes in a Binary Tree is generally considered a medium-level problem. The traversal itself is straightforward, but candidates often struggle with maintaining path-specific state efficiently without recomputing values repeatedly.

Count Dominant Nodes in a Binary Tree Python/Java solution

Python solutions typically use recursive DFS with a helper function carrying maxSoFar as a parameter. Java implementations follow the same idea using class methods and integer tracking. Both versions achieve O(n) time complexity and O(h) space complexity.

How to solve Count Dominant Nodes in a Binary Tree in O(n)?

Use depth-first traversal while carrying the maximum value encountered on the current root-to-node path. At each node, compare the node value with the running maximum and update the answer if the condition is satisfied. Pass the updated maximum to child nodes so every node is processed in constant time.

What is the best approach for Count Dominant Nodes in a Binary Tree?

The best approach is DFS with a running maximum value. During traversal, track the maximum node value seen from the root to the current node. If the current node value is greater than or equal to that maximum, count it as dominant. This solution runs in O(n) time with O(h) recursion stack space.

Is Count Dominant Nodes in a Binary Tree asked at Google/Amazon/Meta?

Binary tree DFS problems with path-state tracking are common in interviews at Google, Amazon, and Meta. Variants of this problem frequently appear under names like Good Nodes in Binary Tree or Visible Nodes. Interviewers use it to evaluate recursion, tree traversal, and state propagation skills.

What data structure is used in Count Dominant Nodes in a Binary Tree?

The primary data structure is a binary tree combined with DFS traversal. Recursive solutions use the call stack implicitly, while iterative implementations use an explicit stack storing pairs of node references and running maximum values.

What is the time complexity of Count Dominant Nodes in a Binary Tree?

The optimal DFS solution runs in O(n) time because each node is visited exactly once. The auxiliary space complexity is O(h), where h is the height of the binary tree due to recursion or an explicit stack.

Comments

Now write it yourselfClose this page and solve Count Dominant Nodes in a Binary Tree in the editor, without looking.
Practise Count Dominant Nodes in a Binary Tree