Tree problems are solved recursively. Focus on what information needs to be returned to the parent node and what information needs to be passed to child nodes.
Time complexity: O(N). Each node is traversed once. Space complexity: O(N). The maximum depth of the tree, which is the recursion depth.
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ classSolution { pair<int, TreeNode*> recurse(TreeNode* root, int depth){ if (root == nullptr) { return {depth, nullptr}; } auto l = recurse(root->left, depth + 1); auto r = recurse(root->right, depth + 1); if (l.first > r.first) { return l; } elseif (l.first == r.first) { return {l.first, root}; } else { return r; } } public: TreeNode* lcaDeepestLeaves(TreeNode* root){ auto ans = recurse(root, 0); return ans.second; } };
1124. Longest Well-Performing Interval
We only care whether each element is greater than 8, not its absolute value. So transform elements greater than 8 into 1, and elements less than or equal to 8 into 0. The problem becomes finding the longest subarray where the number of 1s is greater than the number of 0s.
To quickly calculate how many more 1s than 0s a subarray has, we can use prefix sums.
For example:
[9,9,6,0,6,6,9] -> [1,1,0,0,0,0,1] -> prefix sum [0,1,2,1,0,-1,-2,-3]
The number of 1s minus 0s in subarray [i, j] is prefix[j] - prefix[i - 1], and the array length is j - i + 1.
That is, for each j, we want to find the earliest prefix[i-1] smaller than prefix[j]. Because prefix changes continuously, finding the one exactly smaller than prefix[j] is earlier. For prefix[j] > 0, just find 0.
Another way to find the earliest prefix[i-1] smaller than prefix[j] is to maintain a decreasing stack recording prefix[i], i, then use binary search to find the appropriate prefix[i-1].