This problem asks to find the number of people each person in a grid can see. A person can see another person only if the second person is to the right or below the first person and everyone between them is shorter. The solution uses a monotonic stack to efficiently solve this.
Approach:
The solution cleverly breaks down the problem into two parts: calculating the visible people to the right and the visible people below for each person. Both are handled using a similar approach, relying on the monotonic stack concept.
Monotonic Stack: A monotonic stack maintains a strictly increasing (or decreasing) order. This property makes it exceptionally efficient for finding the nearest greater (or smaller) element. In this problem, we use a decreasing monotonic stack.
Row-wise Calculation: The solution first iterates through each row of the grid. For each row, it uses the helper function f
to calculate the visible people to the right. This function uses a decreasing monotonic stack. As it processes the heights from right to left, it maintains the stack containing heights encountered so far in decreasing order. If a person is taller than the top of the stack, it means they can see all the people shorter than them on the stack, and these people are popped off. The number of popped elements represents the count of visible people.
Column-wise Calculation: After processing all rows, the solution processes the grid column by column. For each column, the same f
function is called to calculate the visible people from below. This is achieved by transposing the view, essentially considering columns as rows.
Combining Results: The results of row-wise and column-wise calculations are summed to get the final answer for each person's visibility.
Time Complexity Analysis:
The f
function iterates through each element of a row or column once. The stack operations (push, pop) take constant time. Therefore, the time complexity of f
is O(n), where n is the length of the row or column. Since f
is called once for each row and once for each column, the overall time complexity of the solution is O(m*n), where m is the number of rows and n is the number of columns. This is linear to the size of the input grid.
Space Complexity Analysis:
The space complexity is dominated by the monotonic stack used in the f
function. In the worst-case scenario, the stack could hold all the elements of a row or column. Therefore, the space complexity is O(max(m, n)). In addition, we need to store the results, which has O(mn) space. Therefore the total space complexity is O(mn).
Code Explanation (Python):
The Python code directly implements the explained approach. The f
function encapsulates the logic of processing a single row or column using the monotonic stack. The main part of the code iterates through rows and columns, applying f
and accumulating the results.
Other Languages:
The Java, C++, Go, and TypeScript codes follow the same algorithm and logic as the Python version, adapting the syntax and data structures specific to each language. The core algorithm remains the same, offering consistent time and space complexity across all implementations.