1. Collect Path Elements for Each Node
Intuition
Store parent pointers or pass path array down to each node. For each node, linearly check if all ancestors are <= node.val.
When to apply: Basic baseline check.
Algorithm
- Step 1: Traverse tree maintaining list of ancestors path.
- Step 2: For each node, check if any value in path is strictly greater than node.val.
- Step 3: If no ancestor is greater, increment good node count.
- Step 4: Recurse on left and right children.
#include <iostream>#include <vector>#include <string>#include <algorithm>using namespace std; class Solution {public: int count = 0; void dfs(TreeNode* node, vector<int>& path) { if (!node) return; bool isGood = true; for (int v : path) { if (v > node->val) { isGood = false; break; } } if (isGood) count++; path.push_back(node->val); dfs(node->left, path); dfs(node->right, path); path.pop_back(); } int goodNodes(TreeNode* root) { vector<int> path; dfs(root, path); return count; }}; int main() { // Sample driver execution cout << "Execution completed successfully." << endl; return 0;} Time & Space Complexity
- Time complexity:
O(n * h)— Linearly checking path of length up to h for each of the n nodes. - Space complexity:
O(h)— Ancestor path array and call stack take O(h) space.