0% completed
Problem Statement
Given a binary tree root
, return the number of good
nodes in the binary tree.
A node is considered good
if in the path from the root to this node, there are no nodes with a value greater than
this node's value.
Examples
Example 1
- Input: root =
[3, 1, 3, 3, null, 1, 5]
- Expected Output:
4
- Explanation:
- Root node (3) is always good.
- Node
5
is also a good node. - Both nodes
3
are good.
Example 2
- Input: root =
[2, 3, 4, 1, null, null, 5]
- Expected Output:
4
- Explanation:
- Nodes
2
,3
,4
, and5
are good. - The node with value
1
is not good because3
is greater and comes before it.
- Nodes
Example 3
- Input: root =
[10, 8, 15, 7, 9, 12, 20]
- Expected Output:
3
- Explanation:
- Nodes
10
,15
, and20
are good.
- Nodes
Constraints:
- The number of nodes in the binary tree is in the range [1, 10^<sup>5</sup>].
- Each node's value is between [-10<sup>4</sup>, 10^<sup>4</sup>].
Solution
To solve this problem, we will use Depth-First Search (DFS) traversal. The idea is to traverse the tree starting from the root and keep track of the maximum value encountered on the path from the root to the current node. If the current node's value is greater than or equal to the maximum value seen so far, it is a good node. We then update the maximum value and continue to traverse the tree.
This approach works because it ensures that we only count a node as good if all nodes on the path from the root to that node have values less than or equal to the current node's value. By updating the maximum value dynamically as we traverse, we can efficiently determine if a node is good.
Step-by-step Algorithm
-
Initialization:
- Start with the root node of the tree.
-
Define Helper Function (DFS):
- Define a helper function
dfs(node, maxVal)
to perform depth-first search (DFS) on the tree. Initially, consider root node's value as amaxVal
. - If the current
node
isnull
, return 0 because there are no nodes to consider.
- Define a helper function
-
Check Good Node:
- Check if the value of the current
node
is greater than or equal tomaxVal
. - If it is, this node is a good node. Initialize a variable
count
to 1. - Otherwise, set
count
to 0.
- Check if the value of the current
-
Update Maximum Value:
- Update
maxVal
to be the maximum of the currentnode
's value and the previousmaxVal
.
- Update
-
Recur for Subtrees:
- Recursively call
dfs
for the left child of the current node with the updatedmaxVal
and add the result tocount
. - Recursively call
dfs
for the right child of the current node with the updatedmaxVal
and add the result tocount
.
- Recursively call
-
Return Count:
- Return the total count of good nodes found in the current subtree.
Algorithm Walkthrough
-
Initialization:
- Start at the root node with value 2.
- Initialize
maxVal
= 2.
-
Step-by-Step DFS Traversal:
-
At Node 2:
maxVal
= 2- 2 >= 2, so node 2 is a good node.
- Count = 1
- Update
maxVal
= max(2, 2) = 2 - Recur for left child (Node 3).
-
At Node 3:
maxVal
= 2- 3 >= 2, so node 3 is a good node.
- Count = 1
- Update
maxVal
= max(2, 3) = 3 - Recur for left child (Node 1).
-
At Node 1:
-
maxVal
= 3 -
1 < 3, so node 1 is not a good node.
-
Count = 0
-
maxVal
remains 3 -
Recur for left and right children (both are null), so return 0 for both.
-
Total count from Node 1's subtree: 0
-
-
Back at Node 3:
- Count from left subtree (Node 1) = 0
- Recur for right child (null), so return 0.
- Total count from Node 3's subtree: 1 (Node 3 itself)
-
Back at Node 2:
- Count from left subtree (Node 3) = 1
- Recur for right child (Node 4).
-
At Node 4:
maxVal
= 2- 4 >= 2, so node 4 is a good node.
- Count = 1
- Update
maxVal
= max(2, 4) = 4 - Recur for left child (null), so return 0.
- Recur for right child (Node 5).
-
At Node 5:
-
maxVal
= 4 -
5 >= 4, so node 5 is a good node.
-
Count = 1
-
Update
maxVal
= max(4, 5) = 5 -
Recur for left and right children (both are null), so return 0 for both.
-
Total count from Node 5's subtree: 1
-
-
Back at Node 4:
- Count from right subtree (Node 5) = 1
- Total count from Node 4's subtree: 2 (Nodes 4 and 5)
-
Back at Node 2:
- Count from right subtree (Node 4) = 2
- Total count from Node 2's subtree: 4 (Nodes 2, 3, 4, 5)
-
-
Final Count:
- The total count of good nodes in the tree is 4.
Code
Complexity Analysis
Time Complexity
The time complexity of this algorithm is O(N), where N is the number of nodes in the tree. This is because we visit each node exactly once during the DFS traversal.
Space Complexity
The space complexity is O(H), where H is the height of the tree. This is due to the recursion stack used during the DFS traversal. In the worst case (for a skewed tree), H can be as large as N, leading to a space complexity of O(N). For a balanced tree, the space complexity would be O(log N).
.....
.....
.....
Table of Contents
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible