Number of Visible People in a Queue
Problem
heights[i] is the (distinct)
height of person i. Person i can see person j > i
when everybody standing strictly between them is shorter than both of them. Return
an array whose i-th entry is how many people person i can see.heights = [10,6,8,5,11,9]Output[3,1,2,1,1,0]heights = [5,1,2,3,10]Output[4,1,1,1,0]1 ≤ n ≤ 105 · 1 ≤ heights[i] ≤ 105 · all heights distinct
Try it yourself
class Solution {
public int[] canSeePersonsCount(int[] heights) {
}
}
i sees a strictly increasing run of
people up to the first one taller than them. Processing from the right with a decreasing
stack, the people i pops are exactly that run, plus one more if someone
taller remains on the stack.Instinct Each element needs its nearest bigger or smaller neighbour (next warmer day, span, widest bar) - keep a sorted stack of waiting indices.
Memory hack Tall people block the view - a newcomer kicks out everyone shorter waiting behind, and each kicked-out person just found their answer.
Open the Monotonic Stack guide →Approaches
Brute ForceCheck Every Pair Directly
O(n3)Space O(1) extraFor each pair (i, j) compute the tallest person strictly
between them and test that both endpoints are taller than it. This is the
visibility rule copied literally.
public int[] canSeePersonsCount(int[] heights) { int n = heights.length; int[] ans = new int[n]; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { int tallestBetween = 0; for (int m = i + 1; m < j; m++) { tallestBetween = Math.max(tallestBetween, heights[m]); } if (Math.min(heights[i], heights[j]) > tallestBetween) ans[i]++; } } return ans; }
Obviously correct, useful as a reference, but cubic.
BetterRunning Maximum with Early Stop
O(n2)Space O(1) extraSweep right from i keeping the tallest person passed so far.
Person j is visible exactly when it beats that running maximum. Once
someone at least as tall as i appears, they block everything
beyond, so stop.
public int[] canSeePersonsCount(int[] heights) { int n = heights.length; int[] ans = new int[n]; for (int i = 0; i < n; i++) { int tallestSoFar = 0; // tallest person between i and j for (int j = i + 1; j < n; j++) { if (heights[j] > tallestSoFar) ans[i]++; tallestSoFar = Math.max(tallestSoFar, heights[j]); if (tallestSoFar >= heights[i]) break; // view is blocked } } return ans; }
Removes the inner loop, but a decreasing line still costs O(n2).
OptimalRight-to-Left Decreasing Stack
O(n)Space O(n)Scan from the right; the stack holds people still visible from the left,
tallest at the bottom. Person i pops everyone shorter — they are
all visible to i and now hidden from anyone further left. If the stack
is still non-empty, its top is the first taller person, also visible.
public int[] canSeePersonsCount(int[] heights) { int n = heights.length; int[] ans = new int[n]; int[] stack = new int[n]; int top = -1; for (int i = n - 1; i >= 0; i--) { int seen = 0; // shorter people are visible to i and hidden for everyone further left while (top >= 0 && stack[top] < heights[i]) { top--; seen++; } if (top >= 0) seen++; // the first taller person is visible too ans[i] = seen; stack[++top] = heights[i]; } return ans; }
Dry runheights = [10,6,8,5,11,9]
- i=510685119ians=0, st=[9]
- i=41068511i9pop 9; ans=1, st=[11]
- i=310685i119top 11; ans=1
- i=21068i5119pop 5 +11; ans=2
- i=1106i85119top 8; ans=1
- i=010i685119pop 6,8 +11; ans=3
Each person is pushed and popped once — linear and clean.
i is taller and stands in front of them.At a glance
| Level | Approach | Time | Space |
|---|---|---|---|
| Brute Force | Check Every Pair Directly | O(n3) | O(1) extra |
| Better | Running Maximum with Early Stop | O(n2) | O(1) extra |
| Optimal | Right-to-Left Decreasing Stack | O(n) | O(n) |
- Counting only people taller than
i— shorter ones can be visible too. - Forgetting the extra +1 for the first taller person left on the stack.
- Not stopping at the first person at least as tall as
iin the O(n2) scan.
- Draw a small example and notice the visible people form an increasing run.
- State the stack invariant: strictly decreasing heights from bottom to top.
- Mention distinct heights; with ties you would have to decide how equals block.